SpringMVC Quick Start [Basic Summary]

Posted by morphy on Mon, 03 Jan 2022 21:23:58 +0100

SpringMVC

brief introduction

What is Spring MVC?

Spring MVC is part of the Spring Framework, or Spring Framework. It is a lightweight Web framework based on Java to implement MVC. Official Documents

Features of Spring MVC?

  • Lightweight, easy to learn.
  • An efficient, request-response-based MVC framework.
  • Good compatibility with Spring and seamless combination.
  • The convention is greater than the configuration.
  • Powerful features such as support: Restful style, data validation, formatting, localization, theme, etc.
  • Introduction Flexibility

The Spring MVC framework is designed around Dispatcher Servlet!

The Dispatcher Servlet is designed to distribute requests to different Controller controllers, and, starting with Spring 2.5, users using Java 5 or above can develop in Spring MVC using annotation-based formats, which is concise and efficient!

Why study Spring MVC?

  • Spring MVC is simple, convenient, easy to learn, highly integrated with Spring's IOC and AOP, and supports Restful style, exception handling, localization, data validation, type conversion, interceptors, etc.
  • Most important point: use more people, use more companies...

Front End Controller/Central Controller (Dispatcher Servlet)

The Spring MVC framework is designed around the Dispatcher Servlet.

Like many other MVC frameworks, the Spring MVC framework is request-driven and distributes requests and dispatches around a central Servlet, Dispatcher Servlet. Common sense is as follows: [Request Distribution and Dispatch]

Dispatcher Servlet is also a Servlet in essence.

As long as the Servlet interface is implemented, it is a Servlet, which inherits from the HttpServlet base class, as follows:

Spring MVC Basic Execution Principles

When a request is made, the front-end controller, Dispatcher Servlet, intercepts the request, generates a proxy request based on the request parameters, finds the actual controller corresponding to the request, namely the JAVA class, the controller processes the request, creates the data model, accesses the database, and responds to the central controller with the model and view, which renders the view results. The result is returned to the front-end controller, which in turn returns the result to the requester.

Execution Flow of SpringMVC

The diagram above is a flowchart of a specific and complete implementation of Spring MVC.

The solid arrow represents the technology provided by the Spring MVC framework, which has already been implemented for us and does not need to be implemented by developers.

The dashed arrow representation requires the developer to code the part of the implementation!!

Its execution process can be divided into three major parts

Part One: Find handlers based on URLs, that is, what adapts the URL requests we pass

1. Dispatcher Servlet represents the Front End Controller/Central Controller, which is the control center for the entire Spring MVC. Users issue requests, Dispatcher Servlet receives requests and intercepts them.

  • Assume that the URL requested by the client is: http://localhost:8080/SpringMVC/hello
  • The URL above can be split into three parts
  • http://localhost:8080 Represents a server domain name
  • SpringMVC represents a web site deployed on a server
  • hello represents the controller Controller
  • That is, the URL above means requesting a hello controller for the SpringMVC site located on server localhost:8080.

2.HandlerMapping is a processor mapping. It is called automatically by Dispatcher Servlet.

  • Handler Mapping is used to find the specified Handler that is the processor based on the URL passed in.

3.HandlerExecution represents a specific Handler whose primary purpose is to find a controller based on a URL, such as the one found above: hello

4.HandlerExecution passes the parsed information to Dispatcher Servlet.

Part two: Find the Controller, which is what you really need to do to adapt this request

5.HandlerAdapter is a processor adapter

  • It looks for a specific Controller according to a specific rule and executes the Handler.

6.Handler lets the specific Controller execute.

7.Controller returns the executed information to the Handler Adapter, such as ModelAndView model and view information

8.HandlerAdapter passes the view logical name or model with data from ModelAndView to Dispatcher Servlet

Part 3: View parser parsing views and rendering data

9.Dispatcher Servlet calls ViewResolver, the view resolver, to resolve the logical view name passed by the Handler Adapter

10.ViewResolver View Parser passes the parsed logical view name to Dispatcher Servlet

11.Dispatcher Servlet calls a specific view based on the result of the view parsed by the ViewResolver View Parser

12. Finally, return the view to the user.

Note: What exactly does the ViewResolver View Parser do?

  1. Get data from ModelAndView
  2. Resolve View Name of ModelAndView
  3. Full path where the stitched view is located
  4. Render data to this view

Dashed Line 1: The developer sets the name of the view that needs to be returned.

Dashed Line 2: Developer sets and encapsulates corresponding data into Model.

Dashed Line 3: Developers write their own code, the Controller layer, to invoke the logical code of a specific Service business layer.

Hello Spring MVC

1. Create a new sub-Module based on the Maven parent project and right-click Add Framework Support to add web application support

2.pom. Dependencies and other related dependencies for importing Spring MVC are identified in XML

pom.xml

<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
</dependency>
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>2.5</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.0.RELEASE</version>
</dependency>

3. Configure the web.xml, register Dispatcher Servlet

web.xml

<?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">

    <!--To configure DispatcherServlet:This is Spring MVC Core:As a request distributor and central controller-->
     <!--this DispatcherServlet Is used spring Already available-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--DispatcherServlet To bind Spring Profile springmvc-servlet.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!--classpath and classpath* Is there a difference:
             classpath: Only to you class Find the file in the path.
             classpath*: Not only contains class Paths, including jar Files ( class Path) to find.
             Note: Use classpath*:Need to traverse all classpath,So the loading speed is very slow;
                  classpath Is WEB-INF Under folder classes Catalog
             Therefore, when planning, you should plan the path of the resource file as well as avoid using it as much as possible. classpath*. -->
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--Configure Startup Level 1:Start the server as soon as it starts-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <!--stay Spring MVC in, / and /*Is there a difference
    / Only matches to/login Such a path type url,Will not match pattern to*.jsp Such a suffix url
    /* Will match all url: Path and Suffix url(Include/login,.jsp,.js and*.html etc.)-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

4. Write a configuration file for the Spring MVC binding in the resources directory

springmvc-servlet.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
       https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--Add to HandlerMapping Processor Mapper,spring Provided in-->
    <!--The specificity of this mapper is based on the incoming URL To find the right one Handler,That is, the corresponding bean-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <!--Add to HandlerAdapter Processor Adapter,spring Provided in-->
    <!--This adapter will look for the appropriate Controller-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

    <!--Add to ViewResolver view resolver,This parser only parses here jsp,Subsequent template parsers can be changed to resolve as needed Freemarker perhaps Thymeleaf-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--Set View Prefix-->
        <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
        <!--Set View Suffix-->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

5. Create a jsp directory in the WEB-INF directory and test for testing under it. jsp files, views are placed in the / WEB-INF / directory, which can ensure the view security, because the files in this directory can not be directly accessed by the client!

test.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>test jsp</title>
</head>
<body>
<!--extract msg Data stored in-->
${msg}

</body>
</html>

6.src directory to write the appropriate Controller

HelloController.java

package com.carson.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//Here you need to implement the Controller interface in Spring mvc to act as a Controller
//A class that implements the Controller interface is a controller.
public class HelloController implements Controller {
    //Override the only method
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //Instantiate an object for a ModelAndView model and view
        ModelAndView mv = new ModelAndView();
        //Location of business code writing
         //The example here only adds data to it, and the parameter of addObject() is a key-value pair
        mv.addObject("msg","Hello Spring MVC!!");
        //View Jump
        mv.setViewName("test");//Correspondence/WEB-INF/html/test.html
        //Return to ModelAndView
        return mv;
    }
}

7. When you have finished writing the Controller, you need to use the Spring configuration file, springmvc-server. Registered bean s in XML as Handler: id corresponds to the request path, and class corresponds to the class that handles the request

springmvc-servlet.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
       https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--Add to HandlerMapping Processor Mapper,spring Provided in-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <!--Add to HandlerAdapter Processor Adapter,spring Provided in-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />

    <!--Add to ViewResolver view resolver,This parser only parses here jsp,Subsequent template parsers can be changed to resolve as needed Freemarker perhaps Thymeleaf-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--Set View Prefix-->
        <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
        <!--Set View Suffix-->
        <property name="suffix" value=".jsp" />
    </bean>
    
    <!--Handler-->
      <!--Because of the above BeanNameUrlHandlerMapping,It will be based on URL In/test To match bean id,This corresponds to the following Handler-->
      <!--So here it is handler Of id Need to/Begin to match URL-->
    <bean id="/hello" class="com.carson.controller.HelloController" />
</beans>

8. Start the tomcat test [where the project's startup path is configured to be empty]

Explain:

  • Implementing an interface Controller to define a controller is an older method and is not recommended!
  • Disadvantages of implementing interface Controller to define controllers are:
    • There can only be one method in a controller, and if more than one method is required, more than one Controller needs to be defined.
    • Defining a controller is a hassle!! Comment development controller is recommended!

Developing Spring MVC using annotations

1. Create a new Module to add support for web applications, just as you did before.

2.pom. The XML determines that dependencies such as Spring MVC, servlet, JSTL have been imported, which has already been imported in the parent dependency.

3. Configure the web.xml

Note:

  1. web.xml version issue, to be the latest version of 4.0!
  2. Register Dispatcher Servlet
  3. Configuration files associated with Spring
  4. Start Level 1
  5. Mapping path is /, do not use /*

web.xml

<?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">

    <!--To configure DispatcherServlet:This is Spring MVC Core:As a request distributor and central controller-->
     <!--this DispatcherServlet Is used spring Already available-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--DispatcherServlet To bind Spring Profile-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!--classpath and classpath* Is there a difference:
             classpath: Only to you class Find the file in the path.
             classpath*: Not only contains class Paths, including jar Files ( class Path) to find.
             Note: Use classpath*:Need to traverse all classpath,So the loading speed is very slow;
                  classpath Is WEB-INF Under folder classes Catalog
             Therefore, when planning, you should plan the path of the resource file as well as avoid using it as much as possible. classpath*. -->
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--Configure Startup Level 1:Start the server as soon as it starts-->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--stay Spring MVC in, / and /*Is there a difference
    / Only matches to/login Such a path type url,Will not match pattern to*.jsp Such a suffix url
    /* Will match all url: Path and Suffix url(Include/login,.jsp,.js and*.html etc.)-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

4. Configure the Spring configuration file springmvc-servlet for the Spring MVC binding under the resources directory. XML

Note:

  1. Let Spring IOC's annotations take effect
  2. Static Resource Filtering: HTML,CSS,JS, Pictures, Videos...
  3. Annotation Driver for MVC
  4. Configure View Parser

springmvc-servlet.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       https://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd
       https://www.springframework.org/schema/mvc
       https://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--Auto Scan Package,Make annotations under the specified package valid,from IOC Unified container management-->
    <!--context:component-scan Specify the package to scan,Comments under this package will take effect-->
    <context:component-scan base-package="com.carson.controller" />

    <!--Give Way Spring MVC Do not process static resources-->
    <mvc:default-servlet-handler />

    <!--Support MVC Annotation Driver
      stay spring Usually used in@RequestMapping Annotations to complete mapping relationships
      To make@RequestMapping Comments take effect
      Must be registered in context DefaultAnnotationHandlerMapping And a AnnotationMethodHandlerAdapter Example
      These two instances are handled at the class and method levels, respectively
      By using this annotaion-driver To configure,Can help us automatically complete the injection of the above two instances
      This configuration helps us to eliminate the previous configuration of processor mappers and adapters
      -->
    <mvc:annotation-driven />

    <!--To configure ViewResolver view resolver,This parser only parses here jsp -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--Set View Prefix-->
        <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
        <!--Set View Suffix-->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

Write the corresponding Controller as a Java control class in the 5.src directory

HelloController.java

package com.carson.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

//The @Controller annotation represents the registration of the Controller into the IOC container, and the String parameter returned by its method corresponds to a view name
//The @Controller annotation indicates that this class will be taken over by Spring
@Controller
//Write mapping paths on classes using the @RequestMapping annotation
@RequestMapping("/HelloController")
public class HelloController {
    //Write the mapping path using the @RequestMapping annotation on the method
    //The actual access address is: localhost:8080/web project name/HelloController/hello
    @RequestMapping("/hello")
    //Any named method that returns a string type in which the Model type parameter can be used to carry data into the view
    public String test01(Model model){
        //Add key-value pair data to a parameter of type Model, which can be taken out of the view and rendered
        model.addAttribute("msg","Hello Spring MVC Annotation!");
        //The returned string is the logical view name, which by default is in the form of request forwarding so that the forwarded view name is stitched together by the view parser
        return "hello";
    }
}

Note:

  • The @Controller annotation is used to declare that an instance of the Spring class is a controller that scans automatically when the Spring IOC container is initialized. If the string returned by its method corresponds to a logical view name, it will be further parsed by the view parser. If you want the string returned by the method to be unparsed by the view parser, you need to add a @ResponseBody comment to the method. If the @RestController annotation is used, the method returns only a string, which will not be further parsed by the view parser!!
  • @RequestMapping is used to map request paths, that is, to map URLs to controller classes or to a specific handler method. It can be on classes or methods; If used on a class, all methods in the class that respond to requests are based on that address as the parent address. That is, the URL address follows the principle of specifying the class path before the method path. In the example above, since there are mappings on both classes and methods, access paths are first class then method: /HelloController/hello
  • Parameters of type Model declared in the method are used to bring data from the Controller into the view.
  • The String type parameter returned by the method corresponds to the logical view name hello, which is prefixed by the view parser with the configuration file to form the full view path: /WEB-INF/jsp/hello.jsp

6. Create View Layer

Create a jsp directory in the WEB-INF directory and a hello for testing under it. jsp files, views are placed in the / WEB-INF / directory, which can ensure the view security, because the files in this directory can not be directly accessed by the client!

hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>hello jsp</title>
</head>
<body>
    <!--Views can be taken out directly Model Data stored in type parameters -->
    ${msg}
</body>
</html>

7. Start the tomcat test [where the project's startup path is configured as SpringMVC_03_annotation]

Summarize the development steps:

  1. Create a new web project
  2. Import Related Dependencies
  3. Write the web.xml, register Dispatcher Servlet
  4. Write Spring MVC dependent Spring profiles
  5. Create the corresponding control class, Controller
  6. Perfect the relationship between front-end view and ontroller and write related functions
  7. test run

There are three main pieces that must be configured to use Spring MVC:

  1. Handler Mapping Processor Mapper
  2. Handler Adapter Processor Adapter
  3. ViewResolver View Parser

By using annotation development, we only need to manually configure the view parser, whereas the processor mapper and the processor adapter only need to turn on the annotation driver, thereby eliminating the relevant xml configuration!!

Note: When the returned JSON data is garbled, the following configuration can be done in the annotation driver to prevent garbage!!

<!--JSON Configuration of Scrambling Problem-->
<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>

Restful Style

brief introduction

  • Restful is a style for locating and manipulating resources

  • It's not a standard or an agreement, it's just a style.

  • Applications based on this style can be simpler, more hierarchical, and easier to implement mechanisms such as caching.

Related concepts

  • Resource: Everything in the Internet can be abstracted as a resource.
  • Resource operation: Use different request methods such as POST, DELETE, PUT, GET to operate on resources, which correspond to the functions of adding, deleting, modifying, querying and so on.

Operating resources in traditional ways

Traditionally: GET/POST requests pass different parameters at the same time to achieve different results!, Examples include the following:

  • http://127.0.0.1/item/query?id=1 [Query Data Request, GET Request, Question Mark Pass Parameter]
  • http://127.0.0.1/item/save [New Data Request, POST Request]
  • http://127.0.0.1/item/update [Update Data Request, POST Request, Question Mark Pass Parameter]
  • http://127.0.0.1/item/delete?id=1 [Delete Data Request, GET Request, Question Mark Pass Parameter]

Use Restful to manipulate resources

Use Restful: Different requests can be made to achieve different results!

The following example requests the same address, but the effect can be different!!

  • http://127.0.0.1/item/1 [Query Data Request, GET Request]
  • http://127.0.0.1/item [New Data Request, POST Request]
  • http://127.0.0.1/item [Update Data Request, PUT Request]
  • http://127.0.0.1/item/1 [Delete data request, DELETE request]

Learning Test Cases

  1. Create a new controller class RestfulController
@Controller
public class RestfulController {
}
  1. The @PathVariable annotation can be used in Spring MVC to bind the value of a method parameter to a URL template variable

If the method parameter name is inconsistent with the variable name in the uri that needs to be bound:

@Controller
public class RestfulController {
    //Map access path, URL template variable format: {template variable name}
    @RequestMapping("/test/{a}/{b}")
    public String index(@PathVariable("a") int p1, @PathVariable("b") int p2, Model model){
        int result = p1+p2;
        //Model type parameter passes data to view (front-end view hello.jsp only writes data that shows msg)
        model.addAttribute("msg","Result"+result);
        //Returns the view location, defaulting to request forwarding, where the forwarded view name is stitched together by the view parser
        return "hello";
    }
}

If the method parameter name is identical to the variable name in the uri that needs to be bound, it can be abbreviated as follows:

@Controller
public class RestfulController {
    //Map access path, URL template variable format: {template variable name}
    @RequestMapping("/test/{p1}/{p2}")
    public String index(@PathVariable int p1, @PathVariable int p2, Model model){
        int result = p1+p2;
        //Model type parameter passes data to view (front-end view hello.jsp only writes data that shows msg)
        model.addAttribute("msg","Result"+result);
        //Returns the view location, defaulting to request forwarding, where the forwarded view name is stitched together by the view parser
        return "hello";
    }
}
  1. Start the tomcat test [here is the project release path: SpringMVC_04_Restful]

Benefits of using path variables?

  1. Make the mapping path simpler and more hierarchical.
  2. It is easier to obtain parameters.
  3. Setting the type of path variable through method parameters constrains the type of front-end access parameters. If the parameter types are inconsistent, the corresponding resources are not accessible. As shown above, both parameter types passed are restricted to int.

Use the annotated method property to specify the type of request

We can narrow the range of requests by constraining the type of request;

The method property in the @RequestMapping annotation corresponds to an enumerated array type RequestMethod

We can use RequestMethod.xx specifies the type of request, such as GET, POST, PUT, DELETE, etc.

The test cases are as follows:

  1. Add a new method to the controller class
//Note: @RequestMapping Note When there are multiple attributes, the setting of the path can be set by either the value attribute or the path attribute
//Map access path (limit request type to POST)
@RequestMapping(value="/hello",method = {RequestMethod.POST})
//Equivalent to: @RequestMapping (path='/hello', method = {RequestMethod.POST})
public String index1(Model model){
    model.addAttribute("msg","hello");
    //Returns the view location, defaulting to request forwarding, where the forwarded view name is stitched together by the view parser
    return "hello";
}
  1. Start tomcat address bar to enter mapped address for testing, error will occur because address bar defaults to GET request

  1. If you limit the request type to GET and access it the same way, it's normal
//Map access path (restrict request type to GET)
@RequestMapping(value="/hello",method = {RequestMethod.GET})
public String index1(Model model){
    model.addAttribute("msg","hello");
    //Returns the view location, defaulting to request forwarding, where the forwarded view name is stitched together by the view parser
    return "hello";
}

Comments that limit the type of request

  • @GetMapping annotation [directly qualifying request types to GET requests only]
    • @GetMapping is equivalent to @RequestMapping(method=RequestMethod.GET)
  • @PostMapping comment [directly qualifying request type can only be Post request]
    • @PostMapping is equivalent to @RequestMapping(method=RequestMethod.POST)
  • @PutMapping comment [directly qualifying request types can only be Put requests]
    • @PutMapping is equivalent to @RequestMapping(method=RequestMethod.PUT)
  • @DeleteMapping comment [directly qualifying request types can only be Delete requests]
    • @DeleteMapping is equivalent to @RequestMapping(method=RequestMethod.DELETE)
  • ...

The test cases are as follows:

  1. A new method has been added to the controller class to limit POST requests, for example:
//Map access path (limit request type to POST)
@PostMapping("/hello")
public String index2(Model model){
    model.addAttribute("msg","hello");
    //Return to view location, default is request forwarding, request forwarding view name is stitched by view parser
    return "hello";
}
  1. Start tomcat address bar input mapping address send GET request for testing:

  1. Change the request type to GET request and retest:
//Map access path (restrict request type to GET)
    @GetMapping("/hello")
    public String index2(Model model){
        model.addAttribute("msg","hello");
        //Returns the view location, defaulting to request forwarding, where the forwarded view name is stitched together by the view parser
        return "hello";
    }

As for other annotations that limit the type of request, the same is true!!

Spring MVC Result Jump Mode

ModelAndView

By setting the ModelAndView object, jumps to the specified page based on the view name viewName and the resolution of the view parser.

Jumped Page = (View Parser Prefix) + viewName + (View Parser Suffix)

View Parser Configured in spring Configuration File

<!--Add to ViewResolver view resolver,Example parsing here jsp,Subsequent changes to parser parse other files-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
    <!--Set View Prefix-->
    <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
    <!--Set View Suffix-->
    <property name="suffix" value=".jsp" />
</bean>

Corresponding Controller Class

//Here you need to implement the Controller interface in Spring mvc to act as a Controller
public class HelloController implements Controller {
    //Override the only method
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //Instantiate an object for a ModelAndView model and view
        ModelAndView mv = new ModelAndView();
        //Location of business code writing
         //The example here only adds data to it, and the parameter of addObject() is a key-value pair
        mv.addObject("msg","Hello Spring MVC!!");
        //View Jump
        mv.setViewName("test");//Correspondence/WEB-INF/html/test.html
        //Return to ModelAndView
        return mv;
    }
}

As mentioned above, this is the oldest method and is not recommended!

Servlet API

Since the core of Spring MVC is Dispatcher Servlet, which is essentially a Servlet, you can set it up by

Servlet's API to jump results without requiring a view parser!

  1. Output to the front end by setting HttpServletResponse.
  2. Redirect by setting HttpServletResponse.
  3. Request forwarding is achieved by setting HttpServletRequest.
@Controller
public class HelloController2 {
    //Output to the front end by setting `HttpServletResponse`
    @RequestMapping("/result/t1")
    public void test1(HttpServletRequest request, HttpServletResponse response) throws IOException {
        response.getWriter().write("Hello,Spring MVC By Servlet API!");
    }
    //Redirect by setting `HttpServletResponse`
    @RequestMapping("result/t2")
    public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException{
        response.sendRedirect("/index.jsp");
    }
    //Request forwarding by setting `HttpServletRequest`
    @RequestMapping("result/t3")
    public void test3(HttpServletRequest request, HttpServletResponse response) throws Exception{
        request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request,response);
    }
}

Although the result jump can be achieved through the Servlet API, this is not recommended!!

Spring MVC

Use Spring MVC for result jumps, but without a view resolver

Before testing, comment out the View Parser section of the Spring configuration file:

spring Profile

<?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
       https://www.springframework.org/schema/beans/spring-beans.xsd
       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">

    <!--Auto Scan Package,Make annotations under the specified package valid,from IOC Unified container management-->
    <!--context:component-scan Specify the package to scan,Comments under this package will take effect-->
    <context:component-scan base-package="com.carson.controller" />
    <!--Give Way Spring MVC Do not process static resources-->
    <mvc:default-servlet-handler />

    <!--Support MVC Annotation Driver-->
    <mvc:annotation-driven />
    
    <!--To configure ViewResolver view resolver,This parser only parses here jsp -->
    <!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        &lt;!&ndash;Set View Prefix&ndash;&gt;
        <property name="prefix" value="/WEB-INF/jsp/" /> &lt;!&ndash;Note that/Ending,Represents the next level of path&ndash;&gt;
        &lt;!&ndash;Set View Suffix&ndash;&gt;
        <property name="suffix" value=".jsp" />
    </bean>-->
</beans>

Corresponding Controller Class

@Controller
public class HelloController3 {
    @RequestMapping("result/t1")
    public String test1(){
        //Request Forwarding
        return "forward:/index.jsp";
    }

    @RequestMapping("result/t2")
    public String test2(){
        //redirect
        return "redirect:/index.jsp";
    }
}

The above ones, which do not use view parsers, are also not recommended!

Use Spring MVC for result jumps, with view parsers

View Parser Configured in spring Configuration File

<!--Add to ViewResolver view resolver,Example parsing here jsp,Subsequent changes to parser parse other files-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
    <!--Set View Prefix-->
    <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
    <!--Set View Suffix-->
    <property name="suffix" value=".jsp" />
</bean>

Corresponding Controller Class

@Controller
public class HelloController3 {
    @RequestMapping("result/t1")
    public String test1(){
        //The string view name returned by default, that is, request forwarding, is spliced by the view parser
        return "test";// Corresponding stitching/WEB-INF/jsp/test.jsp
    }

    @RequestMapping("result/t2")
    public String test2(){
        //Redirection, although there is a view parser, it will not be stitched by the view parser
        return "redirect:/index.jsp";
        //return "redirect:hello"; //hello is another request
    }
}

Recommended use of Spring MVC with view parser!!

Receive Request Data

When the parameter names submitted are the same as those in the processing method

Submit data: http://localhost:8080/hello?name=Carson

Processing method:

@Controller
public class HelloController4 {
    @RequestMapping("/hello")
    //The parameter name passed in from the front end is the same as the parameter name in the following method
    public String test(String name){
        System.out.println("The parameter value passed in is:"+name);
        return "hello";
    }
}

Background output:

When the parameter names submitted and those in the processing method are inconsistent

Submit data: http://localhost:8080/hello?username=Carson

Processing method:

@Controller
public class HelloController4 {
    @RequestMapping("/hello")
    //The parameter name passed in from the front end is different from the parameter name in the following methods
    //You need to add @RequestParam("front-end incoming parameter name") to the method parameter to explain
    public String test(@RequestParam("username") String name){
        System.out.println("The parameter value passed in is:"+name);
        return "hello";
    }
}

Background output:

Recommendation: Incoming front-end request parameters add a @RequestParam() comment to the method parameters to enhance code readability!

Submitted is an object

Require the form field properties submitted to be the same as the object's property name, the parameter of the method in the controller can use the object!

  1. Entity Class
public class User {
    private int id;
    private String name;
    private int age;

    public User() {
    }

    public User(int id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  1. Submit data: http://localhost:8080/user?id=1&name=carson&age=20
  2. Processing method:
@Controller
public class HelloController4 {
    @RequestMapping("/user")
    //Requires that the form field properties submitted match the object's property name, otherwise the object's properties cannot be matched
    //The parameter of the method in the controller can only use the object!
    public String test(User user){
        System.out.println(user);
        return "hello";
    }
}

Background output:

Background Transfer Data to Front End

Through ModelAndView

Examples are as follows:

//Here you need to implement the Controller interface in Spring mvc to act as a Controller
//A class that implements the Controller interface is a controller.
public class HelloController implements Controller {
    //Override the only method
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //Instantiate an object for a ModelAndView model and view
        ModelAndView mv = new ModelAndView();
        //Location of business code writing
         //The example here only adds data to it, and the parameter of addObject() is a key-value pair
        mv.addObject("msg","Hello Spring MVC!!");
        //View Jump
        mv.setViewName("test");//Correspondence/WEB-INF/html/test.html
        //Return to ModelAndView
        return mv;
    }
}

Through ModelMap

Examples are as follows:

@RequestMapping("/HelloController")
public class HelloController {
    @RequestMapping("/hello")
    //Any named method that returns a string type in which the Model type parameter can be used to carry data into the view
    public String test01(ModelMap modelMap){
        //Add key-value pair data to a parameter of type Model, which can be taken out of the view and rendered
        modelMap.addAttribute("msg","Hello Spring MVC!");
        //The returned string is the logical view name, which by default is in the form of request forwarding so that the forwarded view name is stitched together by the view parser
        return "hello";
    }
}

Through Model

Examples are as follows:

@RequestMapping("/HelloController")
public class HelloController {
    @RequestMapping("/hello")
    //Any named method that returns a string type in which the Model type parameter can be used to carry data into the view
    public String test01(Model model){
        //Add key-value pair data to a parameter of type Model, which can be taken out of the view and rendered
        model.addAttribute("msg","Hello Spring!");
        //The returned string is the logical view name, which by default is in the form of request forwarding so that the forwarded view name is stitched together by the view parser
        return "hello";
    }
}

Simple comparison:

  1. There are only a few ways Model can be used to store data, simplifying the understanding and manipulation of Model objects by developers! Mo
  2. ModelMap inherits LinkedHashMap's methods and features, as well as its own partial storage of data.
  3. ModelAndView can set the returned logical view while storing the data to jump the view layer.

Of course, more differences are about performance and optimization, making different choices!!

Scrambling Problem Solution

General Solutions

//Add the following request and response encoding settings to the Servlet
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");

Customize simple coding filters

package com.carson.filter;

import javax.servlet.*;
import java.io.IOException;

public class CharacterEncodingFilter implements Filter {
    //Initialization: When the web server starts, it is automatically initialized, waiting for the filter object to appear
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter Initialized");

    }

    /*
    1:All code in the filter, when filtering a specific request, executes
    2:Chain must be written. The foFilter() method keeps the filter moving forward
    */

    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
		//Convert request and response to HttpServlet type
		HttpServletRequest request = (HttpServletRequest) request;
		HttpServletResponse response = (HttpServletResponse) response;
		//Resolve Chinese scrambling of request parameters
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        //Let our request go on and if it's not written, the program will be stopped here
        //That is, this code means release
        filterChain.doFilter(servletRequest,servletResponse);
        System.out.println("CharacterEncodingFilter After execution");

    }
    //Destroy: When the web server shuts down, it destroys
    public void destroy() {
        System.out.println("CharacterEncodingFilter Destroyed");

    }
}

Encoding filters provided by SpringMVC

SpringMVC provides us with a filter that can be used directly on the web. Configure in XML and use it!

web.xml

<!--To configure SpringMVC Random filter for-->
<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>
<!--Configure Filter Path,with/*take as an example,Filter all paths-->
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

Be careful:

In some extreme cases, this filter does not support GET requests very well!!

So be aware that all encoding settings in the development environment are best set to UTF-8!! [Especially in the tomcat environment]

Generic filter to resolve messy get and post requests

This universal scrambling filter is a defined encoding filter developed by God, which can better solve the problem of get/post request scrambling!

Universal Random Code Filter

package com.carson.filter;
 
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Map;
 
/**
 * Filter to resolve all garbled get and post requests
 */
public class GenericEncodingFilter implements Filter {
 
    @Override
    public void destroy() {
    }
 
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        //Processing character encoding for response
        HttpServletResponse myResponse=(HttpServletResponse) response;
        myResponse.setContentType("text/html;charset=UTF-8");
 
        // Transition to Agreement Related Objects
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        // Enhancement of request packaging
        HttpServletRequest myrequest = new MyRequest(httpServletRequest);
        chain.doFilter(myrequest, response);
    }
 
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }
 
}
 
//Custom request object, wrapper class for HttpServletRequest
class MyRequest extends HttpServletRequestWrapper {
 
    private HttpServletRequest request;
    //Marker whether or not to code
    private boolean hasEncode;
    //Define a constructor that can pass in an HttpServletRequest object to decorate it
    public MyRequest(HttpServletRequest request) {
        super(request);// super must be written
        this.request = request;
    }
 
    // Override Required Enhancement Methods
    @Override
    public Map getParameterMap() {
        // Get Request First
        String method = request.getMethod();
        if (method.equalsIgnoreCase("post")) {
            // post request
            try {
                // Handle post scrambling
                request.setCharacterEncoding("utf-8");
                return request.getParameterMap();
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } else if (method.equalsIgnoreCase("get")) {
            // get request
            Map<String, String[]> parameterMap = request.getParameterMap();
            if (!hasEncode) { // Ensure that get manual encoding logic runs only once
                for (String parameterName : parameterMap.keySet()) {
                    String[] values = parameterMap.get(parameterName);
                    if (values != null) {
                        for (int i = 0; i < values.length; i++) {
                            try {
                                // Handle get scrambling
                                values[i] = new String(values[i]
                                        .getBytes("ISO-8859-1"), "utf-8");
                            } catch (UnsupportedEncodingException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }
                hasEncode = true;
            }
            return parameterMap;
        }
        return super.getParameterMap();
    }
 
    //Take a value
    @Override
    public String getParameter(String name) {
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        if (values == null) {
            return null;
        }
        return values[0]; // Return the first value of the parameter
    }
 
    //Take all values
    @Override
    public String[] getParameterValues(String name) {
        Map<String, String[]> parameterMap = getParameterMap();
        String[] values = parameterMap.get(name);
        return values;
    }
}

You can add the above general encoding filter to your project file as a universal encoding filter!

Then on the web. Configure this filter and filter path in the xml.

Random code problem, usually need more attention, as far as possible in places where you can set the encoding are set to UTF-8 encoding format!!

Using Ajax in Spring MVC

This phase of Ajax demonstrates the use of Ajax based on annotated implementations of JQuery and Spring MVC.

Environment Setup:

  1. web.xml
<?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">
    <!--To configure DispatcherServlet:This is Spring MVC Core:As a request distributor and central controller-->
    <!--this DispatcherServlet Is used spring Already available-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--DispatcherServlet To bind Spring Profile-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationConfig.xml</param-value>
        </init-param>
        <!--Configure Startup Level 1:Start the server as soon as it starts-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--To configure SpringMVC Random filter for,Notice its effect on GET The requested support is not very good-->
    <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>
    <!--Configure Filter Path,with/take as an example,Filter all prefix paths-->
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>
</web-app>
  1. applicationConfig.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       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">

    <!--Auto Scan Package,Make annotations under the specified package valid,from IOC Unified container management-->
    <!--context:component-scan Specify the package to scan,Comments under this package will take effect-->
    <context:component-scan base-package="com.carson.controller" />

    <!--Give Way Spring MVC Do not process static resources-->
    <mvc:default-servlet-handler />

    <!--Support MVC Annotation Driver-->
    <mvc:annotation-driven>
        <!--json Scrambled Configuration-->
        <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>

    <!--To configure ViewResolver view resolver,This parser only parses here jsp -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--Set View Prefix-->
        <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
        <!--Set View Suffix-->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

Example 1:

Front end index.jsp file

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
    <!--Referencing local files JQuery,Be careful script Labels cannot use self-closing labels,To use paired labels-->
    <script src="${pageContext.request.contextPath}/static/js/jquery-3.6.0.js"></script>
    <script>
      function a() {
        $.post({
          url:"${pageContext.request.contextPath}/t2",
          data:{
            name:$("#username").val()
          },
          success:function (data) {
            alert(data);
          }
        })
      }
    </script>
  </head>

  <body>
    <%--When you lose focus,Launch ajax request--%>
    User name:<input type="text" id="username" onblur="a()">

  </body>
</html>

controller

@RestController //The @RestController comment does not parse the returned string through the view parser
public class AjaxController {
    @RequestMapping("/t2")
    public void test1(String name, HttpServletResponse response) throws IOException {
        System.out.println("a1=>param:"+name);
        if("carson".equals(name)){
            response.getWriter().print("true");
        }else{
            response.getWriter().print("false");
        }
    }
}

Effect:

Example 2:

Front end test2.jsp file

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>ajax test2</title>
    <script src="${pageContext.request.contextPath}/static/js/jquery-3.6.0.js"></script>
    <script>
        $(function () {
            $("#btn").click(function () {
                /*Short form: $. post(url, carry param [omitable], success callback function)*/
               $.post("${pageContext.request.contextPath}/t3",function (data) {
                    //console.log(data);
                   let html = "";
                   for(let i=0;i < data.length;i++){
                       html += "<tr>"+"<td>"+data[i].name+"</td>"+"<td>"+data[i].age+"</td>"+"<td>"+data[i].sex+"</td>"+"</tr>"
                   }
                   $("#content").html(html);
               });
            })
        });
    </script>
</head>
<body>

<input type="button" value="Loading data" id="btn">
<table>
    <thead>
        <tr>
            <td>Full name:</td>
            <td>Age:</td>
            <tD>Gender:</tD>
        </tr>
    </thead>
    <tbody id="content">
        <%--data:From Background--%>
    </tbody>
</table>

</body>
</html>

controller

@RestController //The @RestController comment does not parse the returned string through the view parser
public class AjaxController {
    @RequestMapping("/t3")
    public List<User> test2(){
        ArrayList<User> userList = new ArrayList<User>();
        userList.add(new User("Carson1",1,"male"));
        userList.add(new User("Carson2",2,"male"));
        userList.add(new User("Amy",3,"female"));
        return userList;
    }
}

Effect:

Example three:

Front-end login.jsp file

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login test</title>
    <script src="${pageContext.request.contextPath}/static/js/jquery-3.6.0.js"></script>
    <script>
        function checkUsername() {
            $.post({
                url:"${pageContext.request.contextPath}/t4",
                data:{
                    username:$("#userName").val()
                },
                success:function (data) {
                    if(data == "ok"){
                        $("#userInfo").css("color","green");
                    }else{
                        $("#userInfo").css("color","red");
                    }
                    $("#userInfo").html(data);
                }
            })
        };
        function checkPwd() {
            $.post({
                url:"${pageContext.request.contextPath}/t4",
                data:{
                    pwd:$("#pwd").val()
                },
                success:function (data) {
                    if(data == "ok"){
                        $("#pwdInfo").css("color","green");
                    }else{
                        $("#pwdInfo").css("color","red");
                    }
                    $("#pwdInfo").html(data);
                }
            })
        };
    </script>
</head>
<body>
<p>User name:<input type="text" id="userName" οnblur="checkUsername()">
    <span id="userInfo"></span>
</p>
<p>Password:<input type="text" id="pwd" οnblur="checkPwd()">
    <span id="pwdInfo"></span>
</p>

</body>
</html>

controller

@RestController //The @RestController comment does not parse the returned string through the view parser
public class AjaxController {
    @RequestMapping("/t4")
    public String test3(String username,String pwd){
        System.out.println("username yes:"+username);
        System.out.println("pwd yes:"+pwd);
        String msg = "";
        if(username!=null){
            //Normally these data are checked in the database, here is just demo
            if("admin".equals(username)){
                msg = "ok";
            }else if("".equals(username)){
                msg = "User name cannot be empty!";
            }else{
                msg = "Error in username!";
            }
        }

        if(pwd!=null){
            //Normally these data are checked in the database, here is just demo
            if("123456".equals(pwd)){
                msg = "ok";
            }else if("".equals(pwd)){
                msg = "Password cannot be empty!";
            }else{
                msg = "Wrong password!";
            }
        }
        return msg;
    }
}

Effect:

Interceptor

What is an interceptor?

SpringMVC interceptors are similar to Filter filters in Servlet development, which are used to pre-process and post-process processors. Developers can define some interceptors themselves to implement specific functions!!

What is the difference between a filter and an interceptor?

Interceptor is a specific application of AOP's facet-oriented programming idea.

  • Filter
    • As part of the servlet specification, any java web project can be used.
    • Once you configure /* in the url-pattern, you can intercept all the resources you want to access.
    • Filters need to be on the web. Configure in xml.
  • Interceptor
    • Interceptors are the Spring MVC framework itself and can only be used by projects that use the Spring MVC framework.
    • Interceptors will only intercept access to the controller methods, and will not intercept static resource files if they are accessing them!
    • Interceptors are configured in the spring configuration file.

custom interceptor

To customize interceptors, you must implement the HandlerInterceptor interface!

  1. Create a new Maven Model module and add web application support!
  2. Configure the web.xml

web.xml

<?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">
    <!--To configure DispatcherServlet:This is Spring MVC Core:As a request distributor and central controller-->
    <!--this DispatcherServlet Is used spring Already available-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--DispatcherServlet To bind Spring Profile-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationConfig.xml</param-value>
        </init-param>
        <!--Configure Startup Level 1:Start the server as soon as it starts-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--To configure SpringMVC Random filter for,Notice its effect on GET The requested support is not very good-->
    <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>
    <!--Configure Filter Path,with/take as an example,Filter all prefix paths-->
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>
</web-app>
  1. Configure spring Profile

applicationConfig.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       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">

    <!--Auto Scan Package,Make annotations under the specified package valid,from IOC Unified container management-->
    <!--context:component-scan Specify the package to scan,Comments under this package will take effect-->
    <context:component-scan base-package="com.carson.controller" />

    <!--Give Way Spring MVC Do not process static resources-->
    <mvc:default-servlet-handler />

    <!--Support MVC Annotation Driver-->
    <mvc:annotation-driven>
        <!--json Scrambled Configuration-->
        <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>

    <!--To configure ViewResolver view resolver,This parser only parses here jsp -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--Set View Prefix-->
        <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
        <!--Set View Suffix-->
        <property name="suffix" value=".jsp" />
    </bean>
</beans>
  1. Write a custom interceptor class and implement the HandlerInterceptor interface

MyInterceptor.java

package com.carson.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//Interceptor is the concrete reflection of AOP's face-to-face programming thought
public class MyInterceptor implements HandlerInterceptor {
    //This method executes before the request processing method executes
    //It executes the next interceptor (i.e. release request) if it returns true
    //If it returns false, it will not execute the next interceptor (that is, it will not release the request)
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("------------Before request processing------------");
        return true;//Return true, release request
    }
    //This method is executed after the request handling method is executed
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("----------After request processing--------------");

    }
    //This method is executed after dispatcher Servlet processing, mainly for cleanup.
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("-------------DispatcherServlet After treatment,Clean up--------------");
    }
}
  1. Add configuration about interceptors in the spring configuration file

applicationConfig.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       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">

    <!--Auto Scan Package,Make annotations under the specified package valid,from IOC Unified container management-->
    <!--context:component-scan Specify the package to scan,Comments under this package will take effect-->
    <context:component-scan base-package="com.carson.controller" />

    <!--Give Way Spring MVC Do not process static resources-->
    <mvc:default-servlet-handler />

    <!--Support MVC Annotation Driver-->
    <mvc:annotation-driven>
        <!--json Scrambled Configuration-->
        <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>

    <!--To configure ViewResolver view resolver,This parser only parses here jsp -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--Set View Prefix-->
        <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
        <!--Set View Suffix-->
        <property name="suffix" value=".jsp" />
    </bean>

    <!--About Interceptor Configuration,Where multiple interceptors can be configured-->
    <!--Interceptors are SpringMVC Is unique,mvc Start-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--/** Include paths and their subpaths-->
            <!--/admin/* Intercepted is/admin/add And so on , /admin/add/user Will not be intercepted-->
            <!--/admin/** Intercepted is/admin/All paths under,Include subpaths-->
            <mvc:mapping path="/**"/> <!--Configure here to intercept all requests under the root path-->
            <!--adopt bean Interceptors are configured,Select a custom interceptor-->
            <bean class="com.carson.interceptor.MyInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>
  1. Write a Controller to receive requests
//Test Interceptor Controller
@RestController //Use the @RestController annotation to not parse the string returned in the method through the view parser
public class HelloController {
    @RequestMapping("/interceptor")
    public String test1(){
        System.out.println("The method in the controller executed");
        return "OK";
    }
}
  1. Start the tomcat test with the following results:

Verify user logon through interceptor

Ideas for implementation

1. The front end has a landing page with a submission form action.

2. Form submission needs to be processed in the controller. Determine if the username password is correct. If correct, write user information to session. Return login was successful.

3. Interceptors intercept user requests to determine whether users are logged on. If the user is already logged in. No, if the user is not logged in, jump to the landing page.

test

  1. Write front-end related pages

Login landing page. JSP

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login page</title>
</head>
<body>

<h1>Logon Page</h1>
<hr>

<form action="${pageContext.request.contextPath}/user/Login">
    User name:<input type="text" name="username"> <br>
    Password:<input type="password" name="pwd"> <br>
    <input type="submit" value="Submit">
</form>

</body>
</html>

Login success page. JSP

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>login success</title>
</head>
<body>
<h1>Logon success page</h1>
<hr>

${user}Landing Success,Welcome!
<a href="${pageContext.request.contextPath}/user/Logout">Cancellation</a>

</body>
</html>

First page index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>home page</title>
  </head>
  <body>
  <h1>home page</h1>
  <hr>
  <%--Sign in--%>
  <a href="${pageContext.request.contextPath}/user/toLogin">Sign in</a>
  <a href="${pageContext.request.contextPath}/user/toSuccess">Success Page</a>
  </body>
</html>
  1. Write a Controller to process the request

UserController.java

package com.carson.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpSession;

//Controller handling form requests
@Controller
@RequestMapping("/user")
public class UserController {
    //Jump to landing page
    @RequestMapping("/toLogin")
    public String toLogin() throws Exception {
        return "login";//Return to landing page view
    }

    //Jump to Success Page
    @RequestMapping("/toSuccess")
    public String toSuccess() throws Exception {
        return "success";//Return to Landing Success Page View
    }

    //Login Submission
    @RequestMapping("/Login")
    public String login(HttpSession session, String username, String pwd) throws Exception {
        // Log user identity information to session
        System.out.println("Receive Front End username by:"+username);
        session.setAttribute("user", username);
        return "success";//Return to Landing Success Page View
    }

    //Exit Logon
    @RequestMapping("Logout")
    public String logout(HttpSession session) throws Exception {
        // session expiration
        session.invalidate();
        return "login";//Return to landing page view
    }
}
  1. Write user login interceptor

LoginInterceptor.java

package com.carson.interceptor;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;

public class LoginInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        // Release if it is a landing page
        System.out.println("uri: " + request.getRequestURI());
        if (request.getRequestURI().contains("Login")) {
            return true;//Return true, request release
        }
        //Get session information
        HttpSession session = request.getSession();
        // Get data from session information and let go if the user is logged on
        if(session.getAttribute("user") != null) {
            return true;//Return true, request release
        }
        // Users jump to the landing page if they are not logged in
        request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request, response);
        return false; //Return false, request not released
    }

    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

    }
}
  1. Configure the web.xml
<?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">
    <!--To configure DispatcherServlet:This is Spring MVC Core:As a request distributor and central controller-->
    <!--this DispatcherServlet Is used spring Already available-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--DispatcherServlet To bind Spring Profile-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationConfig.xml</param-value>
        </init-param>
        <!--Configure Startup Level 1:Start the server as soon as it starts-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--To configure SpringMVC Random filter for,Notice its effect on GET The requested support is not very good-->
    <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>
    <!--Configure Filter Path,with/take as an example,Filter all prefix paths-->
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>
</web-app>
  1. Configure Spring's profile and register interceptors in it

applicationConfig.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       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">

    <!--Auto Scan Package,Make annotations under the specified package valid,from IOC Unified container management-->
    <!--context:component-scan Specify the package to scan,Comments under this package will take effect-->
    <context:component-scan base-package="com.carson.controller" />

    <!--Give Way Spring MVC Do not process static resources-->
    <mvc:default-servlet-handler />

    <!--Support MVC Annotation Driver-->
    <mvc:annotation-driven>
        <!--json Scrambled Configuration-->
        <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>

    <!--To configure ViewResolver view resolver,This parser only parses here jsp -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--Set View Prefix-->
        <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
        <!--Set View Suffix-->
        <property name="suffix" value=".jsp" />
    </bean>

    <!--About Interceptor Configuration,Where multiple interceptors can be configured-->
    <!--Interceptors are SpringMVC Is unique,mvc Start-->
    <mvc:interceptors>
        <mvc:interceptor>
            <!--/** Include paths and their subpaths-->
            <!--as:/admin/* Intercepted is/admin/add And so on , /admin/add/user Will not be intercepted-->
            <!--as:/admin/** Intercepted is/admin/All paths under,Include subpaths-->
            <mvc:mapping path="/**"/>
            <!--adopt bean Interceptors are configured,Select a custom interceptor-->
            <!--<bean class="com.carson.interceptor.MyInterceptor"/>-->
            <bean class="com.carson.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>
</beans>
  1. Start tomcat test

SpringMVC for file upload and download

File Upload

File upload is the most common feature in project development, and springMVC supports file upload well, but MultipartResolver is not installed by default in the SpringMVC context, so it cannot handle file upload by default.

If you want to use Spring's file upload capabilities, you need to configure MultipartResolver in the context.

Front-end form requirements:

In order to upload files, you must set the form submission method to POST and enctype to multipart/form-data. Only in this case will the browser send the file selected by the user to the server as a binary data stream;

Description of each property of enctype

  • application/x-www-form-urlencoded: The default way for a form to process only the value attribute values in a form field is to use this encoding to process the values in the form field as URL encoding.
  • text/plain: Characters are not encoded except for converting spaces to'+'. Mail is sent directly from the form.
  • multipart/form-data: This encoding process form data as a binary stream, which encapsulates the contents of the file specified in the file field into the request parameters and does not encode the characters.

Example forms that support file upload:

<!--To support file upload,Settings required enctype and post request-->
<form action="" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit">
</form>

As shown above, once enctype is set to multipart/form-data, the browser will process the form data as a binary stream, while the processing of file uploads requires a server-side response to parse the original HTTP.

Advantages of SpringMVC in handling file uploads

  • Although file upload can be done in the Servlet, the implementation is complex! Spring MVC offers simpler encapsulation.

  • Spring MVC provides direct support for file upload, which is implemented using Plug and Play MultipartResolver.

  • Spring MVC uses Apache Commons FileUpload technology to implement a MultipartResolver implementation class: CommonsMultipartResolver. Therefore, SpringMVC file upload also requires components that rely on Apache Commons FileUpload.

File Upload Test

  1. Import related dependencies.

pom.xml

<dependencies>
    <!--Introducing dependencies on file uploads, Maven Will automatically import his dependency packages for us commons-io package-->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.4</version>
    </dependency>
    <!--servlet Dependent version requires 3.0 Above-->
    <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
        </dependency>
</dependencies>
  1. Configuration bean s in the springMVC configuration file:multipartResolver

Note: The id of the configured bean must be: multipartResolver, otherwise uploading the file will be frustrating!

applicationConfig.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"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       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">

    <!--Auto Scan Package,Make annotations under the specified package valid,from IOC Unified container management-->
    <!--context:component-scan Specify the package to scan,Comments under this package will take effect-->
    <context:component-scan base-package="com.carson.controller" />

    <!--Give Way Spring MVC Do not process static resources-->
    <mvc:default-servlet-handler />

    <!--Support MVC Annotation Driver-->
    <mvc:annotation-driven />

    <!--To configure ViewResolver view resolver,This parser only parses here jsp -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--Set View Prefix-->
        <property name="prefix" value="/WEB-INF/jsp/" /> <!--Note that/Ending,Represents the next level of path-->
        <!--Set View Suffix-->
        <property name="suffix" value=".jsp" />
    </bean>

    <!--File Upload Configuration,Use spring Existing CommonsMultipartResolver class-->
    <bean id="multipartResolver"  class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!-- The encoding format of the request must be jSP Of pageEncoding Attributes are consistent so that the contents of the form can be read correctly, defaulting to ISO-8859-1 -->
        <property name="defaultEncoding" value="utf-8"/>
        <!-- Upload file size limit in bytes (10485760)=10M) -->
        <property name="maxUploadSize" value="10485760"/>
        <property name="maxInMemorySize" value="40960"/>
    </bean>
</beans>
  1. Configured web.xml
<?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">
    <!--To configure DispatcherServlet:This is Spring MVC Core:As a request distributor and central controller-->
    <!--this DispatcherServlet Is used spring Already available-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--DispatcherServlet To bind Spring Profile-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationConfig.xml</param-value>
        </init-param>
        <!--Configure Startup Level 1:Start the server as soon as it starts-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--To configure SpringMVC Random filter for,Notice its effect on GET The requested support is not very good-->
    <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>
    <!--Configure Filter Path,with/take as an example,Filter all prefix paths-->
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/</url-pattern>
    </filter-mapping>
</web-app>
  1. Front-end page for testing

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>upload test</title>
</head>
<body>

<!--Front End Upload Page for Tests-->
<!--<form action="/upload2" enctype="multipart/form-data" method="post">-->
<form action="/upload" enctype="multipart/form-data" method="post">
    <input type="file" name="file"/>
    <input type="submit" value="upload">
</form>

</body>
</html>
  1. Write Background Controller: [There are two ways of writing]

One required: CommonsMultipartFile type parameter

Common methods for CommonsMultipartFile type parameters:

  • String getOriginalFilename(): Get the original name of the uploaded file
  • InputStream getInputStream(): Get the file stream
  • void transferTo(File dest): Save the uploaded file to a directory file

5.1 First way to save uploaded files

//Controller for file upload processing
@Controller
public class UploadController {
    //@RequestParam("file") encapsulates the file from the form name=file control into a CommonsMultipartFile object
    //Bulk upload of CommonsMultipartFile is an array
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file , HttpServletRequest request) throws IOException {

        //Get the file name: file.getOriginalFilename();
        String uploadFileName = file.getOriginalFilename();

        //If the file name is empty, go back to the home page directly!
        if ("".equals(uploadFileName)){
            return "redirect:/index.jsp";
        }
        System.out.println("The upload file name is: "+uploadFileName);

        //Upload Path Save Settings
        String path = request.getServletContext().getRealPath("/upload");
        //If the path does not exist, create a new folder under the path
        File realPath = new File(path);
        if (!realPath.exists()){
            realPath.mkdir();
        }
        System.out.println("Save address of uploaded file:"+realPath);

        InputStream is = file.getInputStream(); //Get File Input Stream Object
        OutputStream os = new FileOutputStream(new File(realPath,uploadFileName)); //Set File Output Stream Object

        //Read Write Out
        int len=0;
        byte[] buffer = new byte[1024];//Temporary byte array
        while ((len=is.read(buffer))!=-1){
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        //Back to Home Page
        return "redirect:/index.jsp";
    }
}
  1. 2The second way to save the uploaded file is file.Transto to save the uploaded file
/*
 * Use file.Transto to save the uploaded file
 */
@RequestMapping("/upload2")
public String  fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
 
    //Upload Path Save Settings
    String path = request.getServletContext().getRealPath("/upload");
    //If the path does not exist, create a new folder under the path
    File realPath = new File(path);
    if (!realPath.exists()){
        realPath.mkdir();
    }
    //Upload File Address
    System.out.println("Upload file save address:"+realPath);
 
    //Write files directly through the CommonsMultipartFile method
    file.transferTo(new File(realPath +"/"+ file.getOriginalFilename()));
 
    return "redirect:/index.jsp";
}
  1. Running effect

File Download

File download implementation steps:

1. Set response header

2. Read Files - InputStream

3. Write out the file - OutputStream

4. Perform operations

5. Close the flow (turn on and then off)

Front End Page:

<a href="/download">Test downloaded files,Click Download</a>

Files to download for testing: [Manually placed in the directory corresponding to the output war package]

Background controller Controller:

//File Download
@RequestMapping(value="/download")
public String downloads(HttpServletResponse response , HttpServletRequest request) throws Exception{
    //Resource Address to Download
    String  path = request.getServletContext().getRealPath("/upload");
    String  fileName = "resource.txt";

    //1. Set response header
    response.reset(); //Set page not cached, empty buffer
    response.setCharacterEncoding("UTF-8"); //Character Encoding
    response.setContentType("multipart/form-data"); //Binary Transfer Data
    //Set Response Header
    response.setHeader("Content-Disposition",
                       "attachment;fileName="+ URLEncoder.encode(fileName, "UTF-8"));

    File file = new File(path,fileName);
    //2. Read File--Input Stream
    InputStream input=new FileInputStream(file);
    //3. Write Out File--Output Stream
    OutputStream out = response.getOutputStream();

    byte[] buff =new byte[1024];
    int index=0;
    //4. Perform Write Out
    while((index= input.read(buff))!= -1){
        out.write(buff, 0, index);
        out.flush();
    }
    out.close();
    input.close();
    return null;
}
  1. Operation effect:

Welcome to the Personal Public Number, reply to "SpringMVC" and get all the complete test code in this article!

Topics: Java Spring RESTful Spring MVC