[JAVA] Vérifions la sensation de Spring Boot + Swagger 2.0

Sélectionnez uniquement le Web de https://start.spring.io/ et créez-le rapidement Je n'avais pas Swagger, alors je l'ai apporté du référentiel Maven Veuillez vous référer à build.gradle pour la version etc.

Exemple de code https://github.com/ririkku/swagger-demo

Configuration minimale à essayer

Montant total du code

build.gradle


plugins {
	id 'org.springframework.boot' version '2.2.1.RELEASE'
	id 'io.spring.dependency-management' version '1.0.8.RELEASE'
	id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-web'

	//Minimum requis pour Swagger
	implementation "io.springfox:springfox-swagger2:2.9.2"
	implementation "io.springfox:springfox-swagger-ui:2.9.2"
	
	testImplementation('org.springframework.boot:spring-boot-starter-test') {
		exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
	}
}

test {
	useJUnitPlatform()
}

SwaggerDemoApplication.java


import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SwaggerDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SwaggerDemoApplication.class, args);
    }
}

SwaggerDemoConfiguration.java


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2 // swagger2.Utiliser 0
public class SwaggerDemoConfiguration {

    @Bean
    public Docket petApi() {
        return new Docket(DocumentationType.SWAGGER_2) // Swagger2.Déclaration d'utilisation 0
                .select()
                .paths(PathSelectors.ant("/apis/**"))
                .build();
    }
}

SwaggerDemoRestController.java


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("apis")
public class SwaggerDemoRestController {

    @GetMapping
    public String get() {
        return "get";
    }
}

Vérification

Je commence généralement par Intellij IDEA, mais certaines personnes ne sont pas dans cet environnement, alors je commence par Gradle ./gradlew bootRun Accès sur l'hôte local http://localhost:8080/swagger-ui.html (Comme il ne cadrait pas, il a été divisé en deux) スクリーンショット 2019-12-03 0.04.52.png スクリーンショット 2019-12-03 0.05.09.png

Sentiments divers

L'interface utilisateur est bonne! !! !! Je n'ai pas écrit beaucoup de code et cela pourrait être pratique Mais ça fait beaucoup d'humour, personnalisons-le un peu

Personnaliser les pièces de type en-tête

Code (changer de fichier)

SwaggerDemoConfiguration.java


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2 // swagger2.Utiliser 0
public class SwaggerDemoConfiguration {

    @Bean
    public Docket petApi() {
        return new Docket(DocumentationType.SWAGGER_2) // Swagger2.Déclaration d'utilisation 0
                .select()
                .paths(PathSelectors.ant("/apis/**"))
                .build()
                .apiInfo(new ApiInfoBuilder()
                        .title("Customise Title Swagger Demo Application")
                        .description("Je l'ai personnalisé à mon goût")
                        .contact(new Contact("customise-name", "http://customise-contact", "customise-email"))
                        .version("1.0")
                        .termsOfServiceUrl("http://customise.com")
                        .license("Customise License").licenseUrl("http://customise-license-url") //Texte si seulement licence, lien si licenseUrl est défini
                        .build());
    }
}

Vérification

スクリーンショット 2019-12-03 0.27.24.png

Sentiments divers

L'endroit où le suffixe de «Customise» a été réécrit Puis-je changer les parties de URL de base et http // localhost: 8080 / v2 / api-docs? Impressions De plus, les «extensions» peuvent être définies dans la classe «ApiInfoBuilder» L'utilisez-vous lorsque vous souhaitez créer votre propre plug-in? (https://swagger.io/docs/specification/2-0/swagger-extensions/) Non, à quoi ressemble la méthode Http?

Vérifiez l'interface utilisateur de la méthode HTTP

Code (changer de fichier)

SwaggerDemoRestController.java


import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("apis")
public class SwaggerDemoRestController {

    @GetMapping
    public String get() {
        return "get";
    }

    @PostMapping
    public void post() {
    }

    @DeleteMapping
    public void delete() {
    }

    @PutMapping
    public void put() {
    }

    @PatchMapping
    public void patch() {
    }
}

Vérification

J'ai vu GET il y a quelque temps, donc la prochaine fois je me sens comme POST スクリーンショット 2019-12-03 0.38.16.png スクリーンショット 2019-12-03 0.41.35.png

Sentiments divers

Coloré et facile à voir (PATCH ou quelque chose) Il semble que les détails de l'API seront considérés de différentes manières (code de statut, etc.) Ensuite, personnalisons les détails

Personnalisation des points de terminaison

J'ai changé d'avis et créé une nouvelle classe À dessein, @ PathVariable est lié à une classe, et @ RequestParam est lié à une chaîne!

code

Identifier.java


public class Identifier {

    private String value;

    public Identifier(String value) {
        this.value = value;
    }

    public String value() {
        if (value == null) return "";
        return value;
    }
}

SwaggerDemoCustomiseRestController.java


import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("apis/customise")
public class SwaggerDemoCustomiseRestController {

    @GetMapping("{identifier}")
    public String detail(@RequestHeader("X-Customise-Header") String customiseHeader,
                         @PathVariable("identifier") Identifier identifier,
                         @RequestParam(value = "name", required = false) String name,
                         @RequestParam("limit") int limit) {
        return identifier.value();
    }
}

Vérification

J'ai essayé de mettre @ RequestHeader, @ PathVariable, @ RequestParam Les éléments obligatoires sont maintenant marqués de «requis», ce qui est pratique.

スクリーンショット 2019-12-03 0.56.52.png

Au fait, lorsque vous appuyez sur le bouton «Try it out», l'affichage suivant s'affiche et vous pouvez entrer la valeur et la vérifier!

スクリーンショット 2019-12-03 1.00.22.png

Appuyez sur ʻExecute et vous obtiendrez curl, Request URL, ResponseCode, ResponseBody, ResponseHeaders`!

スクリーンショット 2019-12-03 1.04.11.png スクリーンショット 2019-12-03 1.05.13.png

Sentiments divers

Ça a l'air assez pratique Ensuite, limitons le statut de réponse généré arbitrairement à ce que vous voulez

Spécifier l'état de la réponse

En définissant ʻuseDefaultResponseMessages, seul 200` sera défini par défaut.

Code (changer de fichier)

SwaggerDemoConfiguration.java


import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2 // swagger2.Utiliser 0
public class SwaggerDemoConfiguration {

    @Bean
    public Docket petApi() {
        return new Docket(DocumentationType.SWAGGER_2) // Swagger2.Déclaration d'utilisation 0
                .select()
                .paths(PathSelectors.ant("/apis/**"))
                .build()
                .useDefaultResponseMessages(false) // <-ajouter à
                .apiInfo(new ApiInfoBuilder()
                        .title("Customise Title Swagger Demo Application")
                        .description("Je l'ai personnalisé à mon goût")
                        .contact(new Contact("customise-name", "http://customise-contact", "customise-email"))
                        .version("1.0")
                        .termsOfServiceUrl("http://customise.com")
                        .license("Customise License").licenseUrl("http://customise-license-url") //Texte si seulement licence, lien si licenseUrl est défini
                        .build());
    }
}

Vérification

スクリーンショット 2019-12-03 1.11.07.png

Sentiments divers

Oshisuke a disparu Ensuite, définissons toutes les API des cas susceptibles d'être réellement utilisés.

Définition pratique du point final

Je veux juste utiliser Swagger, donc le contenu de traitement est approprié ou approprié

code

LessonIdentifier.java


class LessonIdentifier {

    private Integer value;

    LessonIdentifier(String value) {
        this.value = Integer.valueOf(value);
    }

    LessonIdentifier(int value) {
        this.value = value;
    }

    Integer value() {
        if (value == null) return 0;
        return value;
    }
}

LessonRequest.java


public class LessonRequest {

    private String studentName;
    private String tutorName;

    public LessonRequest(String studentName, String tutorName) {
        this.studentName = studentName;
        this.tutorName = tutorName;
    }

    public String getStudentName() {
        return studentName;
    }

    public String getTutorName() {
        return tutorName;
    }
}

LessonResponse.java


public class LessonResponse {

    private int id;
    private String studentName;
    private String tutorName;

    LessonResponse(int id, String studentName, String tutorName) {
        this.id = id;
        this.studentName = studentName;
        this.tutorName = tutorName;
    }

    public int getId() {
        return id;
    }

    public String getStudentName() {
        return studentName;
    }

    public String getTutorName() {
        return tutorName;
    }
}

LessonIdentifierResponse.java


public class LessonIdentifierResponse {

    private int value;

    LessonIdentifierResponse(LessonIdentifier lessonIdentifier) {
        this.value = lessonIdentifier.value();
    }

    public int getValue() {
        return value;
    }
}

ErrorResponse.java


public class ErrorResponse {

    private String message;

    public ErrorResponse(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }
}

LessonController.java


import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("apis/lessons")
public class LessonController {

    @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class)
    @GetMapping
    @ResponseStatus(HttpStatus.OK)
    public List<LessonResponse> list() {
        //Processus d'acquisition
        return Arrays.asList(
                new LessonResponse(1, "studentName1", "tutorName1"),
                new LessonResponse(2, "studentName2", "tutorName2"),
                new LessonResponse(3, "studentName3", "tutorName3"));
    }

    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @GetMapping("{lessonIdentifier}")
    @ResponseStatus(HttpStatus.OK)
    public LessonResponse detail(@PathVariable("lessonIdentifier") LessonIdentifier lessonIdentifier) {
        //Processus d'acquisition
        return new LessonResponse(1, "studentName1", "tutorName1");
    }

    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public LessonIdentifierResponse add(@RequestBody LessonRequest lessonRequest) {
        //Traitement supplémentaire
        return new LessonIdentifierResponse(new LessonIdentifier(4));
    }

    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @DeleteMapping("{lessonIdentifier}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void delete(@PathVariable("lessonIdentifier") LessonIdentifier lessonIdentifier) {
        //Supprimer le processus
    }

    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @PutMapping("{lessonIdentifier}")
    @ResponseStatus(HttpStatus.OK)
    public LessonResponse edit(@PathVariable("lessonIdentifier") LessonIdentifier lessonIdentifier,
                               @RequestBody LessonRequest lessonRequest) {
        //Processus d'édition
        return new LessonResponse(1, "EditStudentName1", "EditTutorName1");
    }
}

Vérification

Il y en a beaucoup, donc seulement quelques L'exemple de valeur est bien sorti Et seulement ceux spécifiés par ResponseStatus!

スクリーンショット 2019-12-03 1.42.28.png スクリーンショット 2019-12-03 1.43.52.png スクリーンショット 2019-12-03 1.44.06.png

Sentiments divers

J'en suis arrivé à un point où je peux bien l'utiliser Voulez-vous écrire une explication de l'API? Alors je vais l'écrire

Description détaillée du point final

J'ai essayé d'ajouter @ ApiOperation

Code (changer de fichier)

LessonController.java


import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("apis/lessons")
public class LessonController {

    @ApiOperation(value = "Obtenez une liste de leçons", notes = "Prenez tous les enregistrements sans critères de recherche pour arrêter l'heure dans votre navigateur.")
    @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class)
    @GetMapping
    @ResponseStatus(HttpStatus.OK)
    public List<LessonResponse> list() {
        //Processus d'acquisition
        return Arrays.asList(
                new LessonResponse(1, "studentName1", "tutorName1"),
                new LessonResponse(2, "studentName2", "tutorName2"),
                new LessonResponse(3, "studentName3", "tutorName3"));
    }

    @ApiOperation(value = "Obtenez une leçon", notes = "ID指定したObtenez une leçon")
    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @GetMapping("{lessonIdentifier}")
    @ResponseStatus(HttpStatus.OK)
    public LessonResponse detail(@PathVariable("lessonIdentifier") LessonIdentifier lessonIdentifier) {
        //Processus d'acquisition
        return new LessonResponse(1, "studentName1", "tutorName1");
    }

    @ApiOperation(value = "Créer une leçon", notes = "Après l'avoir créé, il renverra l'ID!")
    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public LessonIdentifierResponse add(@RequestBody LessonRequest lessonRequest) {
        //Traitement supplémentaire
        return new LessonIdentifierResponse(new LessonIdentifier(4));
    }

    @ApiOperation(value = "Supprimer le cours", notes = "Je ne retournerai rien")
    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @DeleteMapping("{lessonIdentifier}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void delete(@PathVariable("lessonIdentifier") LessonIdentifier lessonIdentifier) {
        //Supprimer le processus
    }

    @ApiOperation(value = "Modifier la leçon", notes = "Renvoie la leçon modifiée!")
    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @PutMapping("{lessonIdentifier}")
    @ResponseStatus(HttpStatus.OK)
    public LessonResponse edit(@PathVariable("lessonIdentifier") LessonIdentifier lessonIdentifier,
                               @RequestBody LessonRequest lessonRequest) {
        //Processus d'édition
        return new LessonResponse(1, "EditStudentName1", "EditTutorName1");
    }
}

Vérification

Les détails sont maintenant disponibles!

スクリーンショット 2019-12-03 1.52.23.png スクリーンショット 2019-12-03 1.52.35.png

Sentiments divers

Cependant, je n'aime pas que les messages écrits en @ ApiOperation ou @ ApiResponse deviennent trop longs. .. .. Je vais l'essayer en me demandant s'il peut être transformé en fichier séparé

Définissez le message dans un fichier séparé

code

application.properties


LessonController.list.value=Obtenez une liste de leçons
LessonController.list.notes=Arrêtez le temps dans votre navigateur en prenant tous les enregistrements sans critères de recherche

LessonController.detail.value=Obtenez une leçon
LessonController.detail.notes=Obtenir la leçon avec l'ID spécifié

LessonController.add.value=Créer une leçon
LessonController.add.notes=Après l'avoir créé, il renverra l'ID!

LessonController.delete.value=Supprimer le cours
LessonController.delete.notes=Je ne retournerai rien

LessonController.edit.value=Modifier la leçon
LessonController.edit.notes=Renvoie la leçon modifiée!

LessonController.java


import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import io.swagger.annotations.ApiResponses;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("apis/lessons")
public class LessonController {

    @ApiOperation(value = "${LessonController.list.value}", notes = "${LessonController.list.notes}")
    @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class)
    @GetMapping
    @ResponseStatus(HttpStatus.OK)
    public List<LessonResponse> list() {
        //Processus d'acquisition
        return Arrays.asList(
                new LessonResponse(1, "studentName1", "tutorName1"),
                new LessonResponse(2, "studentName2", "tutorName2"),
                new LessonResponse(3, "studentName3", "tutorName3"));
    }

    @ApiOperation(value = "${LessonController.detail.value}", notes = "${LessonController.detail.notes}")
    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @GetMapping("{lessonIdentifier}")
    @ResponseStatus(HttpStatus.OK)
    public LessonResponse detail(@PathVariable("lessonIdentifier") LessonIdentifier lessonIdentifier) {
        //Processus d'acquisition
        return new LessonResponse(1, "studentName1", "tutorName1");
    }

    @ApiOperation(value = "${LessonController.add.value}", notes = "${LessonController.add.notes}")
    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public LessonIdentifierResponse add(@RequestBody LessonRequest lessonRequest) {
        //Traitement supplémentaire
        return new LessonIdentifierResponse(new LessonIdentifier(4));
    }

    @ApiOperation(value = "${LessonController.delelte.value}", notes = "${LessonController.delete.notes}")
    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @DeleteMapping("{lessonIdentifier}")
    @ResponseStatus(HttpStatus.NO_CONTENT)
    public void delete(@PathVariable("lessonIdentifier") LessonIdentifier lessonIdentifier) {
        //Supprimer le processus
    }

    @ApiOperation(value = "${LessonController.edit.value}", notes = "${LessonController.edit.notes}")
    @ApiResponses(value = {
            @ApiResponse(code = 400, message = "Bad Request", response = ErrorResponse.class),
            @ApiResponse(code = 404, message = "Not Found", response = ErrorResponse.class)})
    @PutMapping("{lessonIdentifier}")
    @ResponseStatus(HttpStatus.OK)
    public LessonResponse edit(@PathVariable("lessonIdentifier") LessonIdentifier lessonIdentifier,
                               @RequestBody LessonRequest lessonRequest) {
        //Processus d'édition
        return new LessonResponse(1, "EditStudentName1", "EditTutorName1");
    }
}

Vérification

Sortons sans aucun problème!

スクリーンショット 2019-12-03 2.16.51.png

Sentiments divers

C'est très pratique lorsque vous souhaitez combiner des messages dans un seul fichier Cependant, si vous n'en faites pas trop, il s'agit généralement d'un fichier de messages compliqué, alors soyez prudent lorsque vous l'utilisez.

Résumé

J'ai compris que cela semble pratique pour le moment Cependant, il y a certaines parties que je n'ai pas pu étudier, comme après Build ou lorsque je ne veux pas que l'environnement de production accède à swagger-ui, alors j'étudierai plus tard.

référence

https://springfox.github.io/springfox/docs/current/

Recommended Posts

Vérifions la sensation de Spring Boot + Swagger 2.0
L'histoire de la montée de la série Spring Boot 1.5 à la série 2.1
Spécifiez le codage des ressources statiques dans Spring Boot
Accédez au h2db intégré de Spring Boot avec jdbcTemplate
05. J'ai essayé de supprimer la source de Spring Boot
J'ai essayé de réduire la capacité de Spring Boot
Vérifiez le comportement de include, exclude et ExhaustedRetryException de Spring Retry
Vérifiez le comportement de getOne, findById et des méthodes de requête avec Spring Boot + Spring Data JPA
L'histoire de la montée de Spring Boot de la série 1.5 à la série 2.1 part2
À propos de la fonction de Spring Boot en raison de différentes versions
Une histoire remplie des bases de Spring Boot (résolu)
Saisissons l'image de fonctionnement (atmosphère) du conteneur DI de Spring
Spring Boot pour la première fois
[Rails] Vérifiez le contenu de l'objet
Sortie de message (Spring boot)
Vérifier l'état de migration des rails
Filtrer le résultat de BindingResult [Spring]
Obtenez une instance proxy du composant lui-même dans Spring Boot
Voir le comportement des mises à jour d'entités avec Spring Boot + Spring Data JPA
Je veux contrôler le message d'erreur par défaut de Spring Boot
[Débutant] Essayez d'écrire l'API REST pour l'application Todo avec Spring Boot
L'histoire de la rencontre avec l'annotation personnalisée Spring
Vérifiez le contenu du magasin de certificats Java
Vérifiez le contenu des paramètres avec le levier
Mémo: [Java] Vérifiez le contenu du répertoire
Étapes pour rendre Spring Boot capable de faire référence à la valeur dans le fichier de propriétés
HTTPS avec Spring Boot et Let's Encrypt
À propos de l'affichage initial de Spring Framework
Mémorandum WebMvcConfigurer de Spring Boot 2.0 (printemps 5)
Vérifiez la version du logiciel Web standard.
[Java] Vérifiez le nombre d'occurrences de caractères
[Java] [Spring] Tester le comportement de l'enregistreur
Vérifiez le fonctionnement de l'interface à travers le thread
Présentation de Spring Boot Actuator, une fonctionnalité qui facilite l'utilisation des applications Spring Boot
Comment vérifier la dernière version de io.spring.platform pour l'écriture dans pom.xml de Spring (STS)
Organisez les différences de comportement de @NotBlank, @NotEmpty et @NotNull avec Spring Boot + Thymeleaf
Obtenez le nom de classe et le nom de méthode du contrôleur exécuté par le HandlerInterceptor de Spring Boot
Obtenez le chemin défini dans la classe Controller de Spring Boot sous forme de liste
Paramètres du gestionnaire de ressources lors de la livraison du SPA avec la fonction de ressource statique de Spring Boot
Comment définir des variables d'environnement dans le fichier de propriétés de l'application Spring Boot
Qu'est-ce que JSP? ~ Connaissons les bases de JSP !! ~
Vérifiez la version de JDK installée et la version de JDK activée
À propos du guide de démarrage officiel de Spring Framework
[FCM] Implémentation de la transmission de messages en utilisant FCM + Spring boot
Ressentez le passage du temps même à Java
Divers tableau de correspondance de Spring Framework et Spring Boot
Lorsque @Transactional of Spring Boot ne fonctionne pas
Le nom officiel de Spring MVC est Spring Web MVC
[Spring Boot] Comment se référer au fichier de propriétés
Afficher la tâche Gradle dans le projet Spring Boot
[Vérification] Comparaison de la vitesse de démarrage de Spring Boot et de Micronaut
[Vérification de comparaison] Quelle est la différence entre la productivité du développement de l'application Spring Boot et celle du passé?
Défi Spring Boot
Faisons un disjoncteur pour le service backend à l'aide de l'actionneur de Spring Boot (partie 1)
[Spring Boot] L'histoire selon laquelle le bean de la classe avec l'annotation ConfigurationProperties n'a pas été trouvé
Forme de botte de printemps
Spring Boot Rappelez-vous