Partage de technologie

apprentissage mvc de printemps

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Chapitre 4 Spring MVC

Section 1 Introduction à Spring MVC

1. Spring MVC

SpringMVC est un framework Java open source et un module indépendant de l'écosystème Spring Framework. Il implémente le framework Web léger basé sur les requêtes du modèle de conception Web MVC (données, entreprise et présentation) basé sur Spring. commodité.

2. Composants principaux de Spring MVC

  • Contrôleur frontal DispatcherServlet

    Responsable de la réception des demandes et de la distribution des demandes

  • Processeur de gestionnaire

    Le processeur comprend des intercepteurs, des méthodes dans le contrôleur, etc., et est principalement responsable du traitement des demandes.

  • Mappeur de processeur HandlerMapping

    Analyser les fichiers de configuration, analyser les annotations et faire correspondre les requêtes aux processeurs

  • Adaptateur de gestionnaire HandlerAdpter

    Trouvez un processeur correspondant en fonction de la demande. Ce processus est appelé adaptation.

  • Résolveur de vue ViewResolver

    Le résultat obtenu après l'exécution du processeur peut être une vue, mais cette vue est une vue logique (il y a du code logique dans la page, comme des boucles et des jugements), et elle doit être traitée à l'aide d'un résolveur de vue. appelé rendu de la vue.

Section 2 Développement et évolution de Spring MVC

<!--低版本-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>4.0.1</version>
    <scope>provided</scope>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

1. Le nom ou l'ID du bean correspond à la demande d'URL

1.1 Configuration du fichier web.xml
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <!--配置Servlet初始化参数-->
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <!--前置控制器要接收所有的请求,因此在容器启动的时候就应该完成初始化-->
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
Configuration 1.2 spring-mvc.xml
<!--视图解析器:在控制器返回视图的时候生效-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--视图资源的前缀-->
    <property name="prefix" value="/" />
    <!--视图资源的后缀-->
    <property name="suffix" value=".jsp" />
</bean>
<!--处理器映射的方式:使用bean的名字或者id的值来与请求匹配-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
1.3 Écriture du contrôleur
public class UserController extends AbstractController {

    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {
        //这里使用配置的视图解析器进行解析  user => / + user + .jsp => /user.jsp
        return new ModelAndView("user");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
1.4 Configurer le contrôleur
<!--通过id值匹配请求的URL-->
<bean id="/view" class="com.qf.spring.mvc.controller.UserController" />
  • 1
  • 2

Réflexion : Selon cette méthode de correspondance des requêtes, chaque requête nécessite qu'un contrôleur lui corresponde. C'est la même chose que l'utilisation du développement de servlets. Un grand nombre de contrôleurs seront écrits, ce qui entraînera une efficacité de développement extrêmement faible.

Spring 提供了方法名来匹配请求来解决这个问题
  • 1

2. Le nom de la méthode du Bean correspond à la requête

2.1 Analyseur de noms de méthodes

Spring fournit InternalPathMethodNameResolver, un résolveur pour les noms de méthodes dans le contrôleur. La fonction de ce résolveur est d'utiliser le nom de la méthode comme base pour faire correspondre les requêtes URL et l'associer au contrôleur.

2.2 Contrôleur multi-opérations

Spring fournit la classe de contrôleur MultiActionController dont d'autres classes de contrôleur peuvent hériter. Dans ses sous-classes, les développeurs peuvent écrire plusieurs méthodes pour traiter les requêtes, puis utiliser l'analyseur de nom de méthode pour faire correspondre la requête.

2.3 Écriture du contrôleur
public class UserMultiController extends MultiActionController {
    //这个方法就匹配 /login 请求
    //请求格式必须是 
    //ModelAndView 方法名(HttpServletRequest req, HttpServletResponse resp){}
    public ModelAndView login(HttpServletRequest req, HttpServletResponse resp){
        return new ModelAndView("login");
    }

    //这个方法就匹配 /register 请求
    public ModelAndView register(HttpServletRequest req, HttpServletResponse resp){
        return new ModelAndView("register");
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
2.4Configuration spring-mvc.xml
 <!--方法名解析器-->
<bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver" />
<!-- /login 请求使用该bean对象处理-->
<bean id="/login" class="com.qf.spring.mvc.controller.UserMultiController">
    <property name="methodNameResolver" ref="methodNameResolver" />
</bean>
<!-- /register 请求使用该bean对象处理-->
<bean id="/register" class="com.qf.spring.mvc.controller.UserMultiController">
    <property name="methodNameResolver" ref="methodNameResolver" />
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Réflexion : Selon cette méthode de mise en correspondance des requêtes, si un contrôleur doit traiter plusieurs requêtes, cela entraînera le problème d'une grande quantité d'informations de configuration, qui sera difficile à maintenir par la suite. Comment le résoudre ?

Spring 提供了 SimpleUrlHandlerMapping 映射器, 该映射器支持一个控制器与多个请求匹配的同时也解决了配置信息繁多的问题。
  • 1

3. Mappage simple du gestionnaire d'URL

Pour utiliser SimpleUrlHandlerMapping, il vous suffit de modifier la configuration spring-mvc.xml.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--视图解析器:在控制器返回视图的时候生效-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--视图资源的前缀-->
        <property name="prefix" value="/" />
        <!--视图资源的后缀-->
        <property name="suffix" value=".jsp" />
    </bean>

    <!--处理器映射的方式:使用bean的名字或者id的值来与请求匹配-->
<!--    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->
    <!--通过id值匹配请求的URL-->
<!--    <bean id="/view" class="com.qf.spring.mvc.controller.UserController" />-->
    <!--方法名解析器-->
<!--    <bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver" />-->
    <!-- /login 请求使用该bean对象处理-->
<!--    <bean id="/login" class="com.qf.spring.mvc.controller.UserMultiController">-->
<!--        <property name="methodNameResolver" ref="methodNameResolver" />-->
<!--    </bean>-->
    <!-- /register 请求使用该bean对象处理-->
<!--    <bean id="/register" class="com.qf.spring.mvc.controller.UserMultiController">-->
<!--        <property name="methodNameResolver" ref="methodNameResolver" />-->
<!--    </bean>-->
    <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/view">userController</prop>
                <prop key="/user/*">userMultiController</prop>
            </props>
        </property>
    </bean>
    <bean id="userController" class="com.qf.spring.mvc.controller.UserController" />
    <bean id="userMultiController" class="com.qf.spring.mvc.controller.UserMultiController" />
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

Réflexion : à mesure que le développement du projet progresse, de plus en plus de fonctions commerciales sont développées, le nombre de contrôleurs augmentera également et le nombre de correspondances de demandes augmentera également. Cela entraînera également des problèmes difficiles à maintenir plus tard. ?

Spring 提供了 DefaultAnnotationHandlerMapping 映射器,支持使用注解来匹配请求,这样就解决了请求匹配导致配置信息繁多的问题,同时还提升了开发效率。
  • 1

4. Annotez les demandes correspondantes

4.1 Écriture d'un contrôleur
@Controller
public class UserAnnotationController {

    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public String login(){
        return "login";
    }

    @RequestMapping(value = "/register", method = RequestMethod.GET)
    public String register(){
        return "register";
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
4.2Configuration spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
    <!--视图解析器:在控制器返回视图的时候生效-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--视图资源的前缀-->
        <property name="prefix" value="/" />
        <!--视图资源的后缀-->
        <property name="suffix" value=".jsp" />
    </bean>

    <!--处理器映射的方式:使用bean的名字或者id的值来与请求匹配-->
<!--    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->
    <!--通过id值匹配请求的URL-->
<!--    <bean id="/view" class="com.qf.spring.mvc.controller.UserController" />-->
    <!--方法名解析器-->
<!--    <bean id="methodNameResolver" class="org.springframework.web.servlet.mvc.multiaction.InternalPathMethodNameResolver" />-->
    <!-- /login 请求使用该bean对象处理-->
<!--    <bean id="/login" class="com.qf.spring.mvc.controller.UserMultiController">-->
<!--        <property name="methodNameResolver" ref="methodNameResolver" />-->
<!--    </bean>-->
    <!-- /register 请求使用该bean对象处理-->
<!--    <bean id="/register" class="com.qf.spring.mvc.controller.UserMultiController">-->
<!--        <property name="methodNameResolver" ref="methodNameResolver" />-->
<!--    </bean>-->
    <!--<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <props>
                <prop key="/view">userController</prop>
                <prop key="/login">userMultiController</prop>
                <prop key="/register">userMultiController</prop>
            </props>
        </property>
    </bean>
    <bean id="userController" class="com.qf.spring.mvc.controller.UserController" />
    <bean id="userMultiController" class="com.qf.spring.mvc.controller.UserMultiController" />-->
    <!--类上的注解处理器-->
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
    <!--方法上的注解处理器-->
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
    <!--扫描包,使得该包下类以及类中定义的方法上所使用的注解生效-->
    <context:component-scan base-package="com.qf.spring.mvc.controller" />
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

5. Configuration d'une version plus récente

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!--视图解析器:在控制器返回视图的时候生效-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--视图资源的前缀-->
        <property name="prefix" value="/" />
        <!--视图资源的后缀-->
        <property name="suffix" value=".jsp" />
    </bean>
    <!--较新的版本使用该标签开启注解支持-->
    <mvc:annotation-driven />
    <!--扫描包,使得该包下类以及类中定义的方法上所使用的注解生效-->
    <context:component-scan base-package="com.qf.spring.mvc.controller" />
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Section 3 Annotations communes de Spring MVC

1. @Contrôleur

Cette annotation est l'identifiant d'un contrôleur

@Controller
public class UserController{
    
}
  • 1
  • 2
  • 3
  • 4

2. @RequestMapping

Cette annotation est utilisée pour faire correspondre les demandes

@Controller
@RequestMapping("/user")
public class UserController{
    
    @RequestMapping(value="/login", method=RequestMethod.POST)
    public int login(){
        return 1;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

3. @RequestBody

Cette annotation ne peut être appliquée qu'aux paramètres de la méthode et permet d'obtenir des données du corps de la requête et de les injecter dans les paramètres.

@Controller
@RequestMapping("/user")
public class UserController{
    
    @RequestMapping(value="/login", method=RequestMethod.POST)
    public int login(@RequestBody User user){
        return 1;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

4. @ResponseBody

Cette annotation est utilisée pour transmettre des données à la page

@Controller
@RequestMapping("/user")
public class UserController{
    
    @RequestMapping(value="/login", method=RequestMethod.POST)
    @ResponseBody
    public int login(@RequestBody User user){
        return 1;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

5. @RequestParam

Cette annotation ne peut être appliquée qu'aux paramètres de la méthode et permet d'obtenir les données de l'en-tête de la requête et de les injecter dans les paramètres.

@Controller
@RequestMapping("/user")
public class UserController{
    
    @RequestMapping(value="/search", method=RequestMethod.GET)
    @ResponseBody
    public List<User> searchUsers(@RequestParam(value="name") String name){
        return new ArrayList<>();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

6. @PathVariable

Cette annotation ne peut être appliquée qu'aux paramètres de la méthode et est utilisée pour obtenir des données du chemin de la requête et les injecter dans les paramètres.

@Controller
@RequestMapping("/user")
public class UserController{
    // /user/admin
    @RequestMapping(value="/{username}", method=RequestMethod.GET)
    @ResponseBody
    public User queryUser(@PathVariable("username") String username){
        return new User();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

7. @SessionAttributes[Pas important]

Cette annotation ne peut être utilisée que sur les définitions de classe et est utilisée pour insérer des entrées dans la session.

@SessionAttributes(types=User.class) //会将model中所有类型为 User的属性添加到会话中。
@SessionAttributes(value={“user1”, “user2”}) //会将model中属性名为user1和user2的属性添加到会话中。
@SessionAttributes(types={User.class, Dept.class}) //会将model中所有类型为 User和Dept的属性添加到会话中。
@SessionAttributes(value={“user1”,“user2”},types={Dept.class}) //会将model中属性名为user1和user2以及类型为Dept的属性添加到会话中。
  • 1
  • 2
  • 3
  • 4

8. @RequestHeader

Cette annotation ne peut être appliquée qu'aux paramètres de méthode et est utilisée pour obtenir des données à partir des en-têtes de requête.

@RequestMapping("/find")  
public void findUsers(@RequestHeader("Content-Type") String contentType) {//从请求头中获取Content-Type的值
}  
  • 1
  • 2
  • 3

9. @CookieValue

Cette annotation ne peut être appliquée qu'aux paramètres de méthode et est utilisée pour obtenir la valeur du cookie de la requête.

@RequestMapping("/find")  
public void findUsers(@CookieValue("JSESSIONID") String jsessionId) {//从请cookie中获取jsessionId的值
}  
  • 1
  • 2
  • 3

10. @ControllerAdvice

Cette annotation ne peut être appliquée qu'aux classes, indiquant que cette classe est le contrôleur qui gère les exceptions.

/**
 * 异常处理的控制器
 */
@ControllerAdvice //这个注解就是spring mvc提供出来做全局异常统一处理的
public class ExceptionController {
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

11. @ExceptionHandler

Cette annotation ne peut être appliquée qu'aux méthodes des classes identifiées par @ControllerAdvice ou @RestControllerAdvice pour gérer les exceptions.

/**
 * 异常处理的控制器
 */
@ControllerAdvice //这个注解就是spring mvc提供出来做全局异常统一处理的
public class ExceptionController {

    @ExceptionHandler //异常处理器
    @ResponseBody //响应至页面
    public String handleException(Exception e){
        return e.getMessage();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Article 4 JSR-303

1. Introduction au JSR-303

JSR signifie Java Spécification Requests, qui représente des propositions de spécifications Java. JSR-303 est un cadre standard fourni par Java pour la vérification de la validité des données Java Bean. Il définit un ensemble d'annotations de vérification qui peuvent être annotées sur les variables membres et les méthodes d'attribut. Hibernate Validator fournit une implémentation de cette norme.

<dependency>
  <groupId>org.hibernate</groupId>
  <artifactId>hibernate-validator</artifactId>
  <version>6.0.1.Final</version>
  <!-- 最新7.0.1.Final -->
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2. Annotations de vérification

annotationexpliquerannotationexpliquer
@Nuldoit être nul@PasNullne peut pas être nulle
@AssertTrueça doit être vrai@AssertFalseça doit être faux
@MinDoit être un nombre dont la valeur est supérieure ou égale à la valeur minimale spécifiée@MaxDoit être un nombre dont la valeur est inférieure ou égale à la valeur maximale spécifiée
@DécimalMinDoit être un nombre dont la valeur est supérieure ou égale à la valeur minimale spécifiée@DecimalMaxDoit être un nombre dont la valeur est inférieure ou égale à la valeur maximale spécifiée
@Taillelongueur de l'ensemble@ChiffresDoit être un nombre et sa valeur doit se situer dans une plage acceptable
@PasséDoit être une date dans le passé@AvenirDoit être une date future
@ModèleDoit correspondre à une expression régulière@E-mailDoit être au format e-mail
@Longueur(min=,max=)La taille de la chaîne doit être comprise dans la plage spécifiée@Pas videNe peut pas être nul, la longueur est supérieure à 0
@Range(min=,max=,message=)Les éléments doivent être dans la portée appropriée@PasBlankNe peut pas être nul, la longueur de la chaîne est supérieure à 0 (limité aux chaînes)

3. Demande

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>5.3.10</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.3.10</version>
</dependency>
<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>6.0.1.Final</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.78</version>
</dependency>
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
<!-- web.xml -->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/" p:suffix=".jsp" />

    <mvc:annotation-driven>
        <mvc:message-converters>
            <!--处理字符串的消息转换器-->
            <bean class="org.springframework.http.converter.StringHttpMessageConverter" />
            <!--处理JSON格式的消息转换器-->
            <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

    <context:component-scan base-package="com.qf.spring.controller" />
</beans>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.Range;

import javax.validation.constraints.NotNull;

public class User {

    @NotNull(message = "账号不能为空")
    @Length(min = 8, max = 15, message = "账号长度必须为8~15位")
    private String username;

    @NotNull(message = "密码不能为空")
    @Length(min = 8, max = 20, message = "密码长度必须为8~20位")
    private String password;

    @Range(min = 0, max = 120, message = "年龄只能在0~120岁之间")
    private int age;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}


import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.validation.Valid;

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/add")
    @ResponseBody
    public Object saveUser(@Valid User user, BindingResult result){
        if(result.hasErrors()) return result.getAllErrors();
        return 1;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62

Section 5 REPOSANT

1. Introduction à RESTIFUL

Le nom complet de REST est Transfert d'État représentatif,exprimer Transfert d'état représentatif

RESTFUL présente les caractéristiques suivantes :

  • Chaque URI représente une ressource
  • Le client utilise GET, POST, PUT et DELETE pour exploiter les ressources du serveur : GET est utilisé pour obtenir des ressources, POST est utilisé pour créer de nouvelles ressources (il peut également être utilisé pour mettre à jour les ressources), PUT est utilisé pour mettre à jour les ressources et DELETE. Utilisé pour supprimer des ressources

2. Demande REPOSANTE

/user GET => 获取用户资源
/user POST => 增加用户资源
/user PUT => 修改用户资源
/user DELETE => 删除用户资源

/user/{username} GET => 获取指定用户资源  这是RESTFUL风格中子资源的表述方式
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

3. Le support de Spring pour RESTFUL

3.1 @RestController

Cette annotation ne peut être appliquée qu'aux classes et est équivalente à la combinaison des annotations @Controller et @ResponseBody.Indique que les résultats renvoyés après l'exécution de toutes les méthodes de cette classe sont directement affichés sur la page.

3.2 @GetMapping
3.2 @PostMapping
3.2 @PutMapping
3.2 @DeleteMapping

Section 6 Traitement des ressources statiques

1. Raisons pour lesquelles les ressources statiques ne sont pas accessibles

Les ressources statiques incluent html, js, css, images, fichiers de polices, etc. Les fichiers statiques n'ont pas de modèle d'URL, ils ne sont donc pas accessibles par défaut. La raison pour laquelle il est accessible est qu'il existe un servlet global dans Tomcat : org.apache.catalina.servlets.DefaultServlet. Son modèle d'URL est "/", donc les demandes de ressources statiques qui ne peuvent pas correspondre dans le projet sont toutes. géré par cette adresse Servlet. Mais dans SpringMVC, DispatcherServlet utilise également "/" comme modèle d'URL, de sorte que le Serlvet global ne sera plus utilisé dans le projet, ce qui entraînera l'impossibilité d'accéder aux ressources statiques.

2. Solutions

2.1 Option 1

Remplacez simplement le modèle d'URL correspondant à DispathcerServlet par un modèle correspondant autre que "/". Par exemple *.do, *.action. Après cette modification, lors de l'envoi d'une requête, l'URL de la requête doit correspondre à .do ou .action.

2.2 Option 2
<!-- web.xml -->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
  </servlet-mapping>
  • 1
  • 2
  • 3
  • 4
  • 5
2.2 Option 3
<!-- spring-mvc.xml -->
<!-- 
这个handler就是处理静态资源的,它的处理方式就是将请求转会到tomcat中名为default的Servlet 
-->
<mvc:default-servlet-handler/>
<!-- mapping是访问路径,location是静态资源存放的路径 -->
<mvc:resources mapping="/static/**" location="/static/" />
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Section 7 Traitement du code chinois tronqué

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
  <display-name>Archetype Created Web Application</display-name>
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <filter>
    <filter-name>encodingFilter</filter-name>
    <!--字符编码过滤器-->
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <!--编码格式-->
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <init-param>
      <!--强制编码-->
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
</web-app>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41

Section 8 Principe de fonctionnement de Spring MVC

checkMultipart(request); //检测是否是多部分请求,这个只可能在文件上传的时候为真


getHandler(processedRequest); //获取处理器 => 遍历HandlerMapping,找到匹配当前请求的执行器链
//没有找到执行器链 就直接向页面报一个404
noHandlerFound(processedRequest, response);
//找到处理当前请求的适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

//控制器之前执行的拦截器将先执行,如果拦截器不通过,则方法直接结束
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    return;
}
//控制器处理请求,可能会得到一个ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

//控制器之后的拦截器执行
mappedHandler.applyPostHandle(processedRequest, response, mv);
//处理分发的结果:这个结果就是控制器处理后的结果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
//拦截器在控制器给出的结果DispatcherServlet处理后执行
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22