Spring MVC framework understanding

Posted by nodster on Mon, 27 Dec 2021 05:42:33 +0100

1. Integration of spring and Web Environment

1.1 ApplicationContext application context acquisition method

The application context object is obtained through the new ClasspathXmlApplicationContext(spring configuration file), but each time a Bean is obtained from the container, the new ClasspathXmlApplicationContext(spring configuration file) must be written. This disadvantage is that the configuration file is loaded multiple times and the application context object is created multiple times.

In the Web project, you can use the ServletContextListener to listen to the start of the Web application. When the Web application starts, we can load the Spring configuration file, create the application context object ApplicationContext, and store it in the largest domain servletContext domain, so that the application context ApplicationContext object can be obtained from the domain at any location.

1.2 handwritten cases

① create listener

package com.terence.listener;

import com.terence.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ContextLoaderListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent servletContextEvent) {
        ServletContext servletContext = servletContextEvent.getServletContext();
        //Read web Global parameters in XML
        String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");
        ApplicationContext app = new ClassPathXmlApplicationContext(contextConfigLocation);
        //Store the application context object of Spring in the ServletContext domain
        servletContext.setAttribute("app",app);
        System.out.println("spring Container creation completed....");
    }

    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

② create a tool class to obtain the A pplicationContext object

package com.terence.listener;

import org.springframework.context.ApplicationContext;

import javax.servlet.ServletContext;

public class WebApplicationContextUtils {

    public static ApplicationContext getWebApplicationContext(ServletContext servletContext){
        return (ApplicationContext) servletContext.getAttribute("app");
    }

}

③ Create a test class for the servlet

package com.terence.web;

import com.terence.listener.WebApplicationContextUtils;
import com.terence.service.UserService;
import org.springframework.context.ApplicationContext;

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

public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        //ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");
        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        UserService userService = app.getBean(UserService.class);
        userService.save();
    }
}

④ configure webapp / 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">
    <!--Global initialization parameters-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>

    <!--Configure listener-->
    <listener>
        <listener-class>com.terence.listener.ContextLoaderListener</listener-class>
    </listener>

    <!--Configuration test servlet-->
    <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>com.terence.web.UserServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/userServlet</url-pattern>
    </servlet-mapping>
</web-app>

⑤ Testing

Browser access

http://localhost:8080/spring_mvc/userServlet

Console output succeeded

1.3. Spring provides tools for obtaining application context

The handwriting case above is just for your convenience. Spring provides a listener, ContextLoaderListener, which encapsulates the above functions. The listener internally loads the spring configuration file, creates the application context object, and stores it in the ServletContext domain. It provides a client tool WebApplicationContextUtils for users to obtain the application context object.

So there are only two things we need to do:

① On the web Configure ContextLoaderListener listener in XML (import spring web coordinates)

② Get the application context object ApplicationContext using WebApplicationContextUtils

1.3. 1 coordinates of importing Spring integrated web

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>

1.3. 2. Configure the ContextLoaderListener listener

<!--Global initialization parameters-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>

<!--Spring Monitor for-->
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

1.3. 3 use WebApplicationContextUtils to obtain the application context object

ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
UserService userService = app.getBean(UserService.class);

2. Introduction to spring MVC

2.1 spring MVC overview

Spring MVC is a request driven lightweight Web framework based on Java to implement MVC design model. It is a follow-up product of spring framework and has been integrated into Spring Web Flow.

Spring MVC has become one of the most popular MVC frameworks, and with spring 3 0, comprehensively surpassing struts 2 and becoming the best MVC framework. Through a set of annotations, it makes a simple Java class a controller for processing requests without implementing any interface. It also supports RESTful programming style requests.

2.2 spring MVC quick start

Requirements: the client initiates the request, the server receives the request, executes logic and jumps the view.

Implementation of development steps

① Import spring MVC related coordinates

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-web</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>
<!--SpringMVC coordinate-->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.0.5.RELEASE</version>
</dependency>
<!--Servlet coordinate-->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.0.1</version>
    <scope>provided</scope>
</dependency>
<!--Jsp coordinate-->
<dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.2.1</version>
    <scope>provided</scope>
</dependency>

② Configuring the spring MVC core controller DispathcerServlet

<servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

③ create Controller class and success JSP} view page

public class UserController {
    public String save(){
        System.out.println("Controller save running....");
        return "success.jsp";
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>Success!</h1>
</body>
</html>

④ Use the annotation to configure the mapping address of the business method in the Controller class

@Controller
public class UserController {
    // Request address http://localhost:8080/user/quick
    @RequestMapping(value="/quick")
    public String save(){
        System.out.println("Controller save running....");
        return "success.jsp";
    }
}

⑤ Configure spring MVC core file spring MVC xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.alibaba.com/schema/stat"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.alibaba.com/schema/stat http://www.alibaba.com/schema/stat.xsd">
    <!--Controller Component scan for-->
    <context:component-scan base-package="com.terence"></context:component-scan>
</beans>

⑥ Client initiated request test

http://localhost:8080/spring_mvc/quick 

Console printing

Page display

2.3 spring MVC process diagram

2.4 key points of knowledge

Development steps of spring MVC

① Import spring MVC related coordinates

② Configuring the spring MVC core controller DispathcerServlet

③ Create Controller classes and view pages

④ Use the annotation to configure the mapping address of the business method in the Controller class

⑤ Configure spring MVC core file spring MVC xml

⑥ Client initiated request test

3. Spring MVC component parsing

3.1 execution process of spring MVC

① The user sends a request to the front-end controller DispatcherServlet.

② The dispatcher servlet receives a request to call the handler mapping processor mapper.

③ The processor mapper finds the specific processor (which can be found according to the xml configuration and annotation), generates the processor object and the processor interceptor (if any) and returns it to the dispatcher servlet.

④ Dispatcher servlet calls HandlerAdapter processor adapter.

⑤ The HandlerAdapter invokes a specific processor (Controller, also known as back-end Controller) through adaptation.

⑥ The Controller returns ModelAndView after execution.

⑦ The HandlerAdapter returns the controller execution result ModelAndView to the dispatcher servlet.

⑧ The dispatcher servlet passes the ModelAndView to the viewrestrover view parser.

⑨ The viewrestrover returns the specific View after parsing.

⑩ DispatcherServlet renders the View according to the View (that is, fills the View with model data). DispatcherServlet responds to the user.

3.2 spring MVC component parsing

3.2. 1 front end controller: DispatcherServlet

When the user requests to reach the front-end controller, it is equivalent to C in MVC mode. The dispatcher servlet is the center of the whole process control

It calls other components to process user requests. The existence of dispatcher servlet reduces the coupling between components.

3.2. 2 processor mapper: HandlerMapping

HandlerMapping is responsible for finding the Handler, that is, the processor, according to the user's request. Spring MVC provides different mappers to implement different functions

Mapping mode, such as configuration file mode, implementation interface mode, annotation mode, etc.

3.2. 3 processor adapter: HandlerAdapter

The processor is executed through the HandlerAdapter, which is an application of adapter mode. More types of processing can be performed through the extension adapter

The actuator.

3.2. 4 processor: Handler

It is the specific business controller to be written in our development. The dispatcher servlet forwards the user request to the Handler. from

Handler handles specific user requests.

3.2. 5 View Resolver: View Resolver

The View Resolver is responsible for generating the processing results into the View view. The View Resolver first resolves the logical View name into the physical View name, that is, the specific page address, and then generates the View object. Finally, it renders the View and displays the processing results to the user through the page.

3.2. 6 view: View

Spring MVC framework provides support for many View types, including jstlView, freemarkerView, pdfView, etc. The most common View is jsp. Generally, the model data needs to be displayed to users through pages through page label or page template technology. Programmers need to develop specific pages according to business requirements

3.3 spring MVC annotation parsing

3.3.1 @RequestMapping

Function: used to establish the correspondence between the request URL and the request processing method

Location:

Class, request the first level access directory of the URL. If it is not written here, it is equivalent to the root directory of the application

Method, the second level access directory of the request URL and the first level directory marked with @ ReqquestMapping on the class form an access virtual path

Properties:

value: used to specify the URL of the request. It works the same way as the path attribute

Method: used to specify the method of the request

params: used to specify conditions that restrict request parameters. It supports simple expressions. key and value as like as two peas for the requested parameters must be exactly the same as those configured.

For example:

params = {"accountName"}, indicating that the request parameter must have accountName

params = {"moeny!100"}, indicating that money in the request parameter cannot be 100

3.3. 2 component scanning

1.mvc namespace introduction

Namespace: xmlns: Context=“ http://www.springframework.org/schema/context "
        xmlns:mvc="http://www.springframework.org/schema/mvc"
Constraint address: http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/mvc 
        http://www.springframework.org/schema/mvc/spring-mvc.xsd

Spring MVC is based on the spring container, so during spring MVC operation, you need to store the controller in the spring container. If you use @ controller annotation, you need to use < context: component scan base package = "com. Terence. Controller" / > to scan the components.

<!--Controller Component scan for-->
<context:component-scan base-package="com.terence">
    <!--Scan only com.terence Under the bag Controller annotation-->
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    <!--Do not scan com.terence Under the bag Controller annotation
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>-->
</context:component-scan>

3.4 XML configuration parsing of spring MVC

Spring MVC has a default component configuration, and the default components are dispatcherservlet Properties configuration file, which is located at org / springframework / Web / servlet / dispatcherservlet Properties, the default view parser is configured in this file, as follows:

org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver

By browsing the parser source code, you can see the default settings of the view parser, as follows:

REDIRECT_URL_PREFIX = "redirect:" -- redirect prefix
 FORWARD_URL_PREFIX = "forward:" -- forwarding prefix (default)
prefix = "";     -- View name prefix
 suffix = "";     -- View name suffix

We can modify the pre suffix of the view by attribute injection

<!--Configure internal resource view parser-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/views/"></property>
  <property name="suffix" value=".jsp"></property>
</bean>

4. Request and response of spring MVC

4.1 data response of spring MVC

4.1. 1. Data response of spring MVC - data response mode (understanding)

① Page Jump

Returns a string directly

Return via ModelAndView object

② Write back data

Returns a string directly

Returns an object or collection

4.1. 2. Data response of spring MVC - page Jump - return string form (application)

4.1. 3 data response of spring MVC - page Jump - return ModelAndView form 1 (application)

In the Controller, the method returns the ModelAndView object and sets the view name

@RequestMapping(value="/quick2")
public ModelAndView save2(){
    /*
        Model:Model action encapsulates data
        View: View function: display data
     */
    ModelAndView modelAndView = new ModelAndView();
    //Set model data
    modelAndView.addObject("username","itcast");
    //Set view name
    modelAndView.setViewName("success");

    return modelAndView;
}

4.1. 4 data response of spring MVC - page Jump - return ModelAndView form 2 (application)

n directly declare ModelAndView on the method parameter in the Controller. You do not need to create it yourself in the method. You can directly use the object in the method to set the view, and you can also jump to the page

@RequestMapping(value="/quick3")
public ModelAndView save3(ModelAndView modelAndView){
    modelAndView.addObject("username","itheima");
    modelAndView.setViewName("success");
    return modelAndView;
}

@RequestMapping(value="/quick4")
public String save4(Model model){
    model.addAttribute("username","Erudite Valley");
    return "success";
}

4.1. 5 data response of spring MVC - page Jump - return to modelandview3 (application)

You can directly use the native httpservertrequest object on the formal parameters of the Controller method, just declare it

@RequestMapping(value="/quick5")
public String save5(HttpServletRequest request){
    request.setAttribute("username","Kuding fish");
    return "success";
}

4.1. 6 data response of spring MVC - write back data - write back string directly (application)

The response object injected through the spring MVC framework uses response getWriter(). Print ("hello world") writes back data. At this time, view jump is not required, and the return value of the business method is void

Return the string to be written back directly, but at this time, you need to inform the spring MVC framework through the @ ResponseBody annotation that the string returned by the method is not a jump, but directly returned in the http response body

@RequestMapping(value="/quick6")
public void save6(HttpServletResponse response) throws IOException {
    response.getWriter().print("hello itcast");
}

@RequestMapping(value="/quick7")
@ResponseBody  //Tell the spring MVC framework to respond directly to data without view jump
public String save7() throws IOException {
    return "hello itheima";
}

4.1. 7 data response of spring MVC - write back data - write back json format string directly (application)

@RequestMapping(value="/quick8")
@ResponseBody
public String save8() throws IOException {
    return "{\"username\":\"zhangsan\",\"age\":18}";
}

It is troublesome to manually splice json format strings. Complex java objects are often converted into json format strings in development. We can use jackson, the json conversion tool learned in the web stage, to convert json format strings and return character strings

@RequestMapping(value="/quick9")
@ResponseBody
public String save9() throws IOException {
    User user = new User();
    user.setUsername("lisi");
    user.setAge(30);
    //Use the json conversion tool to convert the object into a json format string and return it
    ObjectMapper objectMapper = new ObjectMapper();
    String json = objectMapper.writeValueAsString(user);

    return json;
}

4.1. 8 data response of spring MVC - write back data - return object or collection (application)

Spring MVC helps us to convert and write back json strings to objects or collections, configure message conversion parameters for the processor adapter, and specify the use of jackson to convert objects or collections. Therefore, spring MVC XML is configured as follows:

<!--Configure processor mapper-->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/>
        </list>
    </property>
</bean>
@RequestMapping(value="/quick10")
@ResponseBody
//Spring MVC is expected to automatically convert users to json formatted strings
public User save10() throws IOException {
    User user = new User();
    user.setUsername("lisi2");
    user.setAge(32);

    return user;
}

4.1. 9 data response of spring MVC - write back data - return object or collection 2 (application)

Adding @ ResponseBody to the method can return a string in json format, but this configuration is troublesome and there are many configured codes. Therefore, we can use mvc annotation driven instead of the above configuration

<!--mvc Annotation driven-->
<mvc:annotation-driven/>

Among the components of spring MVC, processor mapper, processor adapter and view parser are called the three components of spring MVC.

Use < MVC: annotation driven / > to automatically load RequestMappingHandlerMapping and

RequestMappingHandlerAdapter (processing adapter), which can be used in the Spring-xml.xml configuration file

< MVC: annotation driven / > replaces the configuration of annotation processors and adapters.

Use < MVC: annotation driven / >

By default, the bottom layer will integrate jackson to convert json format strings of objects or collections

4.1. 10 data response of spring MVC - Summary of knowledge points (understanding, memory)

1) Page Jump

Returns a string directly

Return via ModelAndView object

2) Write back data

Returns a string directly

The HttpServletResponse object writes back data directly, the HttpServletRequest object brings back data, the Model object brings back data, or @ ResponseBody writes back string data

Returns an object or collection

@ResponseBody+<mvc:annotation-driven/>

4.2 spring MVC request

4.2. 1. Spring MVC request - get request parameters - request parameter type (understood)

The format of client request parameters is: name = value & name = value

In order to obtain the requested parameters, the server sometimes needs to encapsulate the data. Spring MVC can receive the following types of parameters

Basic type parameters

POJO type parameters

Array type parameter

Set type parameter

4.2. 2 spring MVC request - get request parameters - get basic type parameters (application)

The parameter name of the business method in the Controller should be consistent with the name of the request parameter, and the parameter value will be mapped and matched automatically. And can automatically do type conversion;

Automatic type conversion refers to the conversion from String to other types

http://localhost:8080/itheima_springmvc1/quick9?username=zhangsan&age=12

@RequestMapping(value="/quick11")
@ResponseBody
public void save11(String username,int age) throws IOException {
    System.out.println(username);
    System.out.println(age);
}

4.2. 3 spring MVC request - get request parameters - get POJO type parameters (application)

The property name of the POJO parameter of the business method in the Controller is consistent with the name of the request parameter, and the parameter value will be mapped and matched automatically.

package com.terence.domain;

public class User {

    private String username;
    private int age;

    public String getUsername() {
        return username;
    }

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

    public int getAge() {
        return age;
    }

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

    @Override
    public String toString() {
        return "User{" +
                "username='" + username + '\'' +
                ", age=" + age +
                '}';
    }
}
@RequestMapping(value="/quick12")
@ResponseBody
public void save12(User user) throws IOException {
    System.out.println(user);
}

4.2. 4 spring MVC request - get request parameters - get array type parameters (application)

The name of the business method array in the Controller is consistent with the name of the request parameter, and the parameter value will be mapped and matched automatically.

@RequestMapping(value="/quick13")
@ResponseBody
public void save13(String[] strs) throws IOException {
    System.out.println(Arrays.asList(strs));
}

4.2. 5 spring MVC request - get request parameters - get collection type parameter 1 (application)

When obtaining set parameters, the set parameters should be wrapped in a POJO.

<form action="${pageContext.request.contextPath}/user/quick14" method="post">
    <%--Indicates that it is the first User Object username age--%>
    <input type="text" name="userList[0].username"><br/>
    <input type="text" name="userList[0].age"><br/>
    <input type="text" name="userList[1].username"><br/>
    <input type="text" name="userList[1].age"><br/>
    <input type="submit" value="Submit">
</form>
package com.terence.domain;

import java.util.List;

public class VO {

    private List<User> userList;

    public List<User> getUserList() {
        return userList;
    }

    public void setUserList(List<User> userList) {
        this.userList = userList;
    }

    @Override
    public String toString() {
        return "VO{" +
                "userList=" + userList +
                '}';
    }
}
@RequestMapping(value="/quick14")
@ResponseBody
public void save14(VO vo) throws IOException {
    System.out.println(vo);
}

4.2. 6 spring MVC request - get request parameters - get collection type parameters 2 (application)

When submitting with ajax, you can specify the content type as json, so using @ RequestBody in the method parameter position can directly receive the collection data without using POJO for packaging

<script src="${pageContext.request.contextPath}/js/jquery-3.3.1.js"></script>
<script>
    var userList = new Array();
    userList.push({username:"zhangsan",age:18});
    userList.push({username:"lisi",age:28});
    
    $.ajax({
        type:"POST",
        url:"${pageContext.request.contextPath}/user/quick15",
        data:JSON.stringify(userList),
        contentType:"application/json;charset=utf-8"
    });

</script>
@RequestMapping(value="/quick15")
@ResponseBody
public void save15(@RequestBody List<User> userList) throws IOException {
    System.out.println(userList);
}

4.2. 7 spring MVC request - get request parameters - enable static resource access (application)

When static resources need to be loaded, such as jquery files, it is found that they are not loaded into jquery files through the Google developer tool. The reason is that the URL pattern of the DispatcherServlet, the front-end controller of spring MVC, is configured as /, which means that all resources are filtered. We can specify the release of static resources in the following two ways:

Method 1: in spring MVC Specify the released resources in the XML configuration file

<!--Access to development resources-->
<mvc:resources mapping="/js/**" location="/js/"/>
<mvc:resources mapping="/img/**" location="/img/"/>

Method 2: use < MVC: default servlet handler / > tag

<mvc:default-servlet-handler/>

4.2. 8 spring MVC request - get request parameters - configure global garbled filter (application)

When post requests, the data will be garbled. We can set a filter to filter the encoding.

<!--Configuring global filtering filter-->
<filter>
    <filter-name>CharacterEncodingFilter</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>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

4.2. 9 spring MVC request - get request parameters - parameter binding annotation @ requestparam (application)

When the requested parameter name is inconsistent with the business method parameter name of the Controller, the binding displayed through the @ RequestParam annotation is required

<form action="${pageContext.request.contextPath}/quick16" method="post">
    <input type="text" name="name"><br>
    <input type="submit" value="Submit"><br>
</form>
@RequestMapping(value="/quick16")
@ResponseBody
public void save16(@RequestParam(value="name",required = false,defaultValue = "itcast") String username) throws IOException {
    System.out.println(username);
}

4.2. 10 spring MVC request - get request parameters - get Restful style parameters (application)

Restful is a software architecture style and design style, not a standard, but provides a set of design principles and constraints. It is mainly used for interactive software between client and server. The software designed based on this style can be more concise, more hierarchical, and easier to implement cache mechanism.

Restful style requests use "url + request method" to indicate the purpose of a request. The four verbs in the HTTP protocol indicating the operation method are as follows:

GET: used to GET resources

POST: used to create a new resource

PUT: used to update resources

DELETE: used to DELETE resources

For example:

/user/1 GET: get the user with id = 1

/user/1 DELETE: delete the user with id = 1

/user/1 PUT: update user with id = 1

/user POST: new user

1 in the above url address / user/1 is the request parameter to be obtained. Placeholders can be used for parameter binding in spring MVC. The address / user/1 can be written as / user/{id}, and the placeholder {id} corresponds to the value of 1. In the business method, we can use the @ PathVariable annotation to match and obtain placeholders.

// localhost:8080/user/quick17/zhangsan
@RequestMapping(value="/quick17/{name}")
@ResponseBody
public void save17(@PathVariable(value="name") String username) throws IOException {
    System.out.println(username);
}
 

4.2. 11 spring MVC request - get request parameters - custom type converter (application)

Spring MVC provides some common type converters by default, such as converting the string submitted by the client to int for parameter setting.

However, not all data types are provided with converters. If not, custom converters are required. For example, custom converters are required for date type data.

package com.terence.converter;

import org.springframework.core.convert.converter.Converter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateConverter implements Converter<String, Date> {
    public Date convert(String dateStr) {
        //Returns a date string converted to a date object
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = null;
        try {
            date = format.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return date;
    }
}
@RequestMapping(value="/quick18")
@ResponseBody
public void save18(Date date) throws IOException {
    System.out.println(date);
}

4.2. 12 spring MVC request - get request parameters - get Servlet related API (application)

Spring MVC supports using the original servlet API object as the parameter of the controller method for injection. The common objects are as follows:

HttpServletRequest

HttpServletResponse

HttpSession

@RequestMapping(value="/quick19")
@ResponseBody
public void save19(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws IOException {
    System.out.println(request);
    System.out.println(response);
    System.out.println(session);
}

4.2. 13 spring MVC request - get request parameters - get request header information (application)

Using @ RequestHeader, you can obtain the request header information, which is equivalent to the request learned in the web stage getHeader(name)

@The attributes of the RequestHeader annotation are as follows:

value: the name of the request header

required: whether this request header must be carried

@RequestMapping(value="/quick20")
@ResponseBody
public void save20(@RequestHeader(value = "User-Agent",required = false) String user_agent) throws IOException {
    System.out.println(user_agent);
}

Use @ Cookie value to get the value of the specified Cookie

@The properties of the CookieValue annotation are as follows:

value: Specifies the name of the cookie

required: do you have to carry this cookie

@RequestMapping(value="/quick21")
@ResponseBody
public void save21(@CookieValue(value = "JSESSIONID") String jsessionId) throws IOException {
    System.out.println(jsessionId);
}

5. File upload of spring MVC

5.1 spring MVC request - file upload - client form implementation (application)

The file upload client form needs to meet the following requirements:

Form item type = "file"

The form is submitted by post

The enctype attribute of the form is a multi part form, and enctype = "multipart / form data"

<form action="${pageContext.request.contextPath}/user/quick22" method="post" enctype="multipart/form-data">
    name<input type="text" name="username"><br/>
    File 1<input type="file" name="uploadFile"><br/>
    Document 2<input type="file" name="uploadFile2"><br/>
    <input type="submit" value="Submit">
</form>

5.2 spring MVC request - file upload - principle of file upload (understanding)

5.3 code implementation of spring MVC request - file upload - single file upload 1 (application)

Add dependency

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.3</version>
</dependency>

Configure multimedia parser

<!--Profile upload parser-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"/>
    <property name="maxUploadSize" value="500000"/>
</bean>

Background program

@RequestMapping(value="/quick22")
@ResponseBody
public void save22(String username, MultipartFile uploadFile) throws IOException {
    System.out.println(username);
    System.out.println(uploadFile);
}

5.4 code implementation of spring MVC request - file upload - single file upload 2 (application)

Complete file upload

@RequestMapping(value="/quick22")
@ResponseBody
public void save22(String username, MultipartFile uploadFile,MultipartFile uploadFile2) throws IOException {
    System.out.println(username);
    //Get the name of the uploaded file
    String originalFilename = uploadFile.getOriginalFilename();
    uploadFile.transferTo(new File("C:\\upload\\"+originalFilename));
    String originalFilename2 = uploadFile2.getOriginalFilename();
    uploadFile2.transferTo(new File("C:\\upload\\"+originalFilename2));
}

5.5 spring MVC request - file upload - code implementation of multi file upload (application)

To upload multiple files, you only need to change the page to multiple file upload items and change the method parameter MultipartFile type to MultipartFile []

<form action="${pageContext.request.contextPath}/user/quick23" method="post" enctype="multipart/form-data">
    name<input type="text" name="username"><br/>
    File 1<input type="file" name="uploadFile"><br/>
    Document 2<input type="file" name="uploadFile"><br/>
    <input type="submit" value="Submit">
</form>
@RequestMapping(value="/quick23")
@ResponseBody
public void save23(String username, MultipartFile[] uploadFile) throws IOException {
    System.out.println(username);
    for (MultipartFile multipartFile : uploadFile) {
        String originalFilename = multipartFile.getOriginalFilename();
        multipartFile.transferTo(new File("C:\\upload\\"+originalFilename));
    }
}

5.6 spring MVC request - key points of knowledge (understanding, memory)

6. Interceptor of spring MVC

6.1 spring MVC interceptor - role of interceptor (understanding)

The interceptor of Spring MVC is similar to the Filter in Servlet development, which is used to preprocess and post process the processor.

The interceptors are connected into a chain in a certain order. This chain is called InterceptorChain. When accessing the intercepted methods or fields, the interceptors in the interceptor chain will be called in the order previously defined. Interceptors are also the concrete implementation of AOP ideas.

6.2 spring MVC interceptor - difference between interceptor and filter (understanding, memory)

The difference between interceptor and filter is shown in the figure:

6.3 spring MVC interceptor - Quick Start (application)

The custom interceptor is very simple. There are only three steps:

① Create an interceptor class to implement the HandlerInterceptor interface

② Configure interceptor

③ Test the interception effect of the interceptor

Write Interceptor:

public class MyInterceptor1 implements HandlerInterceptor {
    //Execute before the target method executes
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        System.out.println("preHandle.....");
        String param = request.getParameter("param");
        if("yes".equals(param)){
            return true;
        }else{
            request.getRequestDispatcher("/error.jsp").forward(request,response);
            return false;//Returning true means release, and returning false means no release
        }
    }

    //Execute after the target method executes and before the view object returns
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        modelAndView.addObject("name","itheima");
        System.out.println("postHandle...");
    }

    //Execute after all processes are executed
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion....");
    }
}

Configuration: configure in the configuration file of spring MVC

<!--Configuring Interceptors -->
<mvc:interceptors>
    <mvc:interceptor>
        <!--Which resources are intercepted-->
        <mvc:mapping path="/**"/>
        <bean class="com.terence.interceptor.MyInterceptor1"/>
    </mvc:interceptor>
</mvc:interceptors>

Write test program:

Write the controller, send a request to the controller and jump to the page

@Controller
public class TargetController {
    @RequestMapping("/target")
    public ModelAndView show(){
        System.out.println("Target resource execution......");
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("name","itcast");
        modelAndView.setViewName("index");
        return modelAndView;
    }
}

jsp page

<html>
<body>
<h2>Hello World! ${name}</h2>
</body>
</html>

Browser access controller

http://localhost:8080/spring_interceptor_war_exploded/target?param=yes

6.4 spring MVC interceptor - quick start details (application)

Under what circumstances will the interceptor execute the target resource after preprocessing, under what circumstances will the interceptor not execute the target resource, and what is the execution order of the interceptor when there are multiple interceptors?

Write another interceptor 2,

public class MyInterceptor2 implements HandlerInterceptor {
    //Execute before the target method executes
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws ServletException, IOException {
        System.out.println("preHandle22222.....");
        return true;
    }

    //Execute after the target method executes and before the view object returns
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        System.out.println("postHandle2222...");
    }

    //Execute after all processes are executed
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        System.out.println("afterCompletion2222....");
    }
}

Configure interceptor 2

<!--Configuring Interceptors -->
<mvc:interceptors>
    <mvc:interceptor>
        <!--Which resources are intercepted-->
        <mvc:mapping path="/**"/>
        <bean class="com.terence.interceptor.MyInterceptor2"/>
    </mvc:interceptor>
    <mvc:interceptor>
        <!--Which resources are intercepted-->
        <mvc:mapping path="/**"/>
        <bean class="com.terence.interceptor.MyInterceptor1"/>
    </mvc:interceptor>
</mvc:interceptors>

The test results are as follows

preHandle22222.....
preHandle.....
Target resource execution......
postHandle...
postHandle2222...
afterCompletion....
afterCompletion2222....

Conclusion:

When the preHandle method of the interceptor returns true, the target resource will be executed. If false, the target resource will not be executed

In the case of multiple interceptors, the configuration before is executed first, and the configuration after is executed

The execution order of methods in the interceptor is: preHandler ------ target resource ----- posthandle ----- aftercompletion

6.5 spring MVC interceptor - knowledge summary (memory)

The method in the interceptor is described below

6.6 spring MVC interceptor - user login permission control analysis (understanding)

On the basis of the day06 spring exercise case: the user cannot access the background menu without logging in. Click the menu to jump to the login page. The background function can be operated only after the user logs in successfully

Demand diagram:

6.7 spring MVC interceptor - user login permission control code implementation 1 (application)

Judge whether the user is logged in: judge whether there is a user in the session. If there is no login, log in first. If there is already login, directly release access to the target resource

First write the interceptor as follows:

public class PrivilegeInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException {
        //Logic: judge whether the user logs in. Essence: judge whether there is a user in the session
        HttpSession session = request.getSession();
        User user = (User) session.getAttribute("user");
        if(user==null){
            //not logged on
            response.sendRedirect(request.getContextPath()+"/login.jsp");
            return false;
        }

        //Release access to target resources
        return true;
    }
}

Then configure the Interceptor: find the spring - MVC XML, add the following configuration:

<!--Configure permission interceptor-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--Configure which resources to intercept-->
        <mvc:mapping path="/**"/>
        <bean class="com.terence.interceptor.PrivilegeInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

6.8 spring MVC interceptor - user login permission control code implementation 2 (application)

Enter the user name and password on the login page, click login, and query through the user name and password. If the login is successful, the user information entity will be stored in the session, and then jump to the home page. If the login fails, continue to return to the login page

Write login logic in UserController

@RequestMapping("/login")
public String login(String username,String password,HttpSession session){
    User user = userService.login(username,password);
    if(user!=null){
        //Login succeeded. Store user in session
        session.setAttribute("user",user);
        return "redirect:/index.jsp";
    }
    return "redirect:/login.jsp";
}

The service layer code is as follows:

public User login(String username, String password) {
    User user = userDao.findByUsernameAndPassword(username,password);
    return user;
}

dao layer code is as follows:

public User findByUsernameAndPassword(String username, String password) throws EmptyResultDataAccessException{
    User user = jdbcTemplate.queryForObject("select * from sys_user where username=? and password=?", new BeanPropertyRowMapper<User>(User.class), username, password);
    return user;
}

At this time, we still can't log in, because we need to let the interceptor release the login request url and add the configuration of resource exclusion

<!--Configure permission interceptor-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--Configure which resources to intercept-->
        <mvc:mapping path="/**"/>

        <!--Which resources are configured to exclude blocking operations-->
        <mvc:exclude-mapping path="/css/**"/>
        <mvc:exclude-mapping path="/plugins/**"/>
        <mvc:exclude-mapping path="/img/**"/>
        <mvc:exclude-mapping path="/user/login"/>
        <bean class="com.terence.interceptor.PrivilegeInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

6.9 spring MVC interceptor - user login permission control code implementation 3 (application)

JdbcTemplate. If the queryforobject object cannot find the data, it will throw an exception, resulting in the program unable to achieve the expected effect. How to solve this problem?

The business layer handles exceptions from the dao layer. If an exception occurs, the service layer returns null instead of throwing the exception to the controller

Therefore, modify the login business layer code and add exception control

public User login(String username, String password) {
    try {
        User user = userDao.findByUsernameAndPassword(username,password);
        return user;
    }catch (EmptyResultDataAccessException e){
        return null;
    }
}

7 spring MVC exception handling mechanism

7.1 ideas for exception handling

There are two types of exceptions in the system: expected exception and runtime exception RuntimeException. The former obtains exception information by capturing exceptions, and the latter mainly reduces the occurrence of runtime exceptions by standardizing code development and testing.

Dao, Service and Controller of the system are thrown upward through throws Exception. Finally, the spring MVC front-end Controller sends it to the exception handler for exception handling, as shown in the following figure:

7.2 two methods of exception handling

① Use the simple exception handler SimpleMappingExceptionResolver provided by Spring MVC

② Implement the exception handling interface of Spring, HandlerExceptionResolver, and customize its own exception handler

7.3 simple exception handler SimpleMappingExceptionResolver

Spring MVC has defined this type converter. When using it, you can map and configure the corresponding exceptions and views according to the project situation

<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <!--<property name="defaultErrorView" value="error"/>-->
    <property name="exceptionMappings">
        <map>
            <entry key="java.lang.ClassCastException" value="error1"/>
            <entry key="com.terence.exception.MyException" value="error2"/>
        </map>
    </property>
</bean>

7.4 custom exception handling steps

① Create an exception handler class to implement HandlerExceptionResolver

public class MyExceptionResolver implements HandlerExceptionResolver {
    /*
        Parameter Exception: Exception object
        Return value ModelAndView: jump to error view information
     */
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        if(e instanceof MyException){
            modelAndView.addObject("info","Custom exception");
        }else if(e instanceof ClassCastException){
            modelAndView.addObject("info","Class conversion exception");
        }
        modelAndView.setViewName("error");
        return modelAndView;
    }
}

② Configure exception handler

<!--Custom exception handler-->
<bean class="com.terence.resolver.MyExceptionResolver"/>

③ Write exception page

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <h1>General error prompt page</h1>
    <h1>${info}</h1>
</body>
</html>

④ Test abnormal jump

public class DemoServiceImpl implements DemoService {
    public void show1() {
        System.out.println("Throw type conversion exception....");
        Object str = "zhangsan";
        Integer num = (Integer)str;
    }

    public void show2() {
        System.out.println("Throw divide by zero exception....");
        int i = 1/0;
    }

    public void show3() throws FileNotFoundException {
        System.out.println("File not found exception....");
        InputStream in = new FileInputStream("C:/xxx/xxx/xxx.txt");
    }

    public void show4() {
        System.out.println("Null pointer exception.....");
        String str = null;
        str.length();
    }

    public void show5() throws MyException {
        System.out.println("Custom exception....");
        throw new MyException();
    }
}
@Controller
public class DemoController {
    @Autowired
    private DemoService demoService;
    @RequestMapping(value = "/show")
    public String show() throws FileNotFoundException, MyException {
        System.out.println("show running......");
        //demoService.show1();
        //demoService.show2();
        //demoService.show3();
        //demoService.show4();
        demoService.show5();
        return "index";
    }
}

Access the controller to test, and the results are as follows

http://localhost:8080/spring_exception_war_exploded/show

Topics: Java Spring Spring MVC mvc