Spring MVC learning summary

Keywords: Java Spring mvc

0. Introduction

        This article is used to record my spring MVC learning content and some of my understanding. The reference materials are from the following:
       Crazy God says Java -- spring MVC
       Common methods of fastjson_ authority39 blog - CSDN blog_ Common methods of fastjson
        There may be some incomprehensible places. Don't spray if you don't like it.

1. Routine development process

2. Features of spring MVC:

  • RESTful style, supporting data verification
  • Concise and flexible

3. Execution process of spring MVC

  • Make sure that the related packages of spring MVC are imported

  • Configure web.xml and register dispatcher Servlet

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    	<!--Associate a springmvc Configuration file for-->
        <init-param>
        	<param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--Startup level: 1-->
    	<load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <!--
    		/ : Match all requests, excluding jsp
    		/*: Match all requests, including jsp
    	-->
    	<servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
  • Set the springmvc-servlet.xml configuration file:

    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <!--Set processor mapper-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
    <!--Set up processor adapter-->
    <bean clss="org.springframework.web.servlet.view.InternalResourceViewResolver" 
          id="InternalResourceViewResolver">
        <!--Jump view prefix-->
    	<property name="prefix" value="/WEB-INF/jsp/" />
        <!--Jump attempt suffix-->
        <property name="suffix" value=".jsp" />
    </bean>
    <!--Set up view parser-->
    
  • Write relevant controller codes:

    public class HelloController implements Controller{
        
        //override method 
        public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)throws Exception{
            ModelAndView modelAndView= new ModelAndView();
            
            //Encapsulate information in ModelAndView
            modelAndView.addObject("msg","HelloSpringMVC");
            //Set jump view
            modelAndView.setViewName("hello");
            //Return to view parser
            return modelAndView;
        }
    }
    
  • Configure the written controller class into springmvc-servlet.xml

    <bean id="/hello" class="xxx.xxx.xxx.HelloController" />
    
  • Workflow: after starting Tomcat, the dispatcher servlet is set and all requests with "/" prefix are received, so the request is sent to the dispatcher servlet, which is then sent to the processor mapper. After processing, it is sent back to the dispatcher servlet, and then the dispatcher servlet is sent to the processor adapter. It is found that the id in springmvc-servlet.xml is matched "/ Hello", then execute the overridden handleRequest() method, return a ModelAndView, which is transferred to the view parser by the dispatcher servlet, and carry the information msg and the view "hello" to jump to , the view parser adds the prefix to get the resource / WEB-INF/jsp/hello.jsp, and passes the information to JSP. After rendering, it returns to dispatcher servlet and then to the front end. (see the picture of crazy God)

  • Possible problems: the JAR package is missing and needs to be imported in the project of IDEA. (add the lib directory to import all requirement packages)

  • Spring MVC execution process (data version):

4. Spring MVC annotation implementation:

  • Configuring the dispatcher servlet in web.xml remains the same;

  • Configure the configuration file of dispatcherservlet. The changes are as follows:

    <beans xmlns=".........................................."
           xmlns:xsi=".........................................."
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="..........................................
                               http://www.springframework.org/schema/context
                               https://www.springframework.org/schema/context/spring-context.xsd
                               http://www.springframework.org/schema/mvc
                               https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <!--Automatically scan the package to make the comments under the specified package effective, and IOC Unified container management-->
        <context:component-scan bean-package="xxx.xxx.xxx" />
        <!--Give Way SpringMVC Do not process static resources   .css .html .js-->
        <mvc:default-servlet-handler />
        <!--support mvc Annotation driven-->
        <mvc:annotation-driven />
        
        ..........................................
        <!--Configure view parser-->
        
    </beans>
    
  • Write Controller layer

    @Controller
    //Indicates that this is a Controller
    //Here, you can also add the annotation @ RequestMapping("/HelloController") to the class
    //In this case, only the request of "localhost:8080/HelloController" can reach the Controller
    public class HelloController{
        @RequestMapping("/hello")
        //url mapping address
        public String hello(Model model){
            model.addAttribute("msg","Hello,SpringMVCAnnotation!");
            return "hello";
            //The content returned to the view parser, that is, the target jsp file name
        }
    }
    
  • If you want to use redirection or redirection, you need to log off the view parser. When you return, the default is to realize forwarding. You can also add the keyword "forward" or "redirect" to realize forwarding and redirection:

    return "redirect:WEB-INF/jsp/index.jsp";
    return "forward:WEB-INF/jsp/index.jsp";
    //But in this case, you need to write the full name because there is no view parser
    
  • Realize parameter transfer at the front and rear ends:

    @RequestMapping("/add")
    public String add(@RequestParam("numFir")int a,@RequestParam("numSec")int b){
        ..........................................
        return "add";
    }
    

    In this way, when the front end accesses "localhost: 8080 / add? Numfir = 1 & numsec = 2", it will jump to this method to perform relevant operations. Here, the annotation "@ RequestParam("... ")" It is used to bind the parameters passed from the front end. If you use a user-defined class to receive parameters, you need to ensure that the property field name in the user-defined class is consistent with the parameter name, otherwise an exception will occur.

5. RestFul style programming:

  • RestFul style programming can effectively protect information in the case of leaking the parameter name under traditional url access:

    Localhost: 8080 / index? Method = add & num1 = 1 & num2 = 2 (access method under traditional programming style)

    Localhost: 8080 / index / add / 1 / 2 (access mode in restful programming style)

  • Different methods such as POST, DELETE, PUT and GET can be used to operate the same resources and obtain different results;

  • Realize the separation of front and back ends: return the data in the form of JSON to the front end

    • When the class annotation is @ Controller, add the annotation @ ResponseBody on the corresponding method, so that the result of the sub return will not go to the view parser, but directly return to the front-end String result;

    • When the class annotation is @ RestController, the return values of all methods in the class will be directly given to the front end instead of the view parser;

    • Use jackson to return data in Json format:

      • Import jackson related dependencies:

        <dependency>
        	<gorupId>com.fasterxml.jackson.core</gorupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.8</version>
        </dependency>
        
      • usage method:

        ObjectMapper mapper = new ObjectMapper();
        Object object = new Object();
        //What is simulated here is only the process of obtaining the parameters required by the front end
        //Suppose the object is the target object
        String str = mapper.writeValueAsString(object);
        return str;
        //In fact, the String returned in this way will be garbled in Chinese
        //You can configure a processor in Spring to solve this problem
        //Repetitive code can be written as tool classes to realize reuse
        //Processing of timestamp objects
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.format(date);//The return value type of this method is String
        //You can also use the format method of setting ObjectMapper
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        mapper.setDateFormat(sdf);
        
      • Solve the problem of Chinese random code in Jason:

        <mvc:annotation-driven>
        	<mvc:message-converters register-defaults="true">
            	<bean class="org.springframework.http.converter.StringHttpMessageConverter">
                	<constructor-arg value="UTF-8" />
                </bean>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="objectMapper">
                    	<bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
                        	<property name="failOnEmptyBeans" value="false" />
                        </bean>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
        
    • Use alibaba's Fastjson package to return data in Json format:

      • Import dependencies related to fastjson

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.66</version>
        </dependency>
        
      • Common methods:

        //Resolve directly to object:
        T t = JSON.parseObject(jsonstr,T,class);
        List<T> list = JSON.parseArray(jsonstr,T.class);
        //Resolve to JSON object:
        Object obj = JSON.parse(jsonstr);
        JSONObject objJSON = JSON.parseObject(jsonstr);
        JSONArray arrJSON = JSON.parseArray(jsonstr);
        
        //Get the data in the JSONArray object:
        JSONObject objJSON = arrJSON.get(i);
        T t = arrJSON.getObject(i,T.class);
        
        //Get data in JSONObject object:
        Integer integer = objJSON.getInteger(key);
        String string = objJSON.getString(key);
        JOSNObject tar = objJSON.getJSONObject(key);
        JSONArray arrJSON = objJSON.getJSONArray(key);
        
        //Format object as json string
        JSON.toJSONString(object);
        //Although the above method can achieve the goal, there are still some problems. The following methods are recommended:
        SerializerFeature quotefieldnames = SerializerFeature.QuoteFieldNames;               
        // The output result is not enclosed in double quotes
        SerializerFeature writemapnullvalue = SerializerFeature.WriteMapNullValue;           
        // Print out fields with null values
        SerializerFeature writenullstringasempty = SerializerFeature.WriteNullStringAsEmpty; 
        // The null value field appears as' '
        SerializerFeature writenulllistasempty = SerializerFeature.WriteNullListAsEmpty;     
        // The array of null values is displayed as []
        JSON.toJSONString(obj, quotefieldnames, writemapnullvalue, writenullstringasempty, writenulllistasempty);
        //This part of the code can be encapsulated and reused
        
  • Usage:

    • You need to add the annotation "@ PathVariable" on the parameters in the relevant methods and modify the corresponding @ RequestMapping

      @Controller
      public class RestFulController{
          
          @RequestMapping(path="/add/{a}/{b}")
          public String add(@PathVariable int a,@PathVariable int b,Model model){
              ..........................................
              return "add";
          }
      }
      
    • To implement multi method response, you need to add a new attribute method in RequestMapping or use composite annotation

      @RequestMapping(path="......",method=RequestMethod.GET)
      @GetMapping("path value")
      

6. Solution to garbled code problem: register filter (you can use Spring's own)

<filter>
	<filter-name>encoding</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>
</filter>
<filter-mapping>
	<filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Posted by expertis on Fri, 24 Sep 2021 08:53:24 -0700