Spring Framework Learning Notes (3) – Spring MVC Framework

Time:2019-10-5

Spring MVC framework is based on Spring framework, which can make it more convenient for us to develop the Web and realize front-end and back-end separation.

Ideas and principles

We defined a custom MVC framework just like Spring MVC, and both ideas are the same.

It is suggested to combine two articles for learning.

JSP Learning Notes (6) – Customized MVC Framework

First, we provide a Dispatch Servlet to intercept URL requests. Then, according to URL requests, we jump to the Controller layer, perform operations, and then return data.

Introduction

My demo uses the Maven framework

1. Create Maven projects

Configure as shown below
Spring Framework Learning Notes (3) - Spring MVC Framework

2. Adding dependencies

Modify pom. XML to add dependencies

At the beginning, the latest version (5.x.x) was used, and then a strange error was found. After a long time, no method was found, so the 4.x.x version was used. As a matter of fact, there was no problem, and the new version was useless.

junit
  junit
  4.11
  test




  commons-logging
  commons-logging
  RELEASE


  org.springframework
  spring-context
  4.3.9.release


  org.springframework
  spring-context-support
  4.3.9.release


  org.springframework
  spring-test
  4.3.9.release


  org.springframework
  spring-core
  4.3.9.release


  org.springframework
  spring-beans
  4.3.9.release


  org.springframework
  spring-expression
  4.3.9.release


  org.springframework
  spring-web
  4.3.9.release


  org.springframework
  spring-webmvc
  4.3.9.release



  org.springframework
  spring-aop
  4.3.9.release



  org.aspectj
  aspectjweaver
  RELEASE


  aopalliance
  aopalliance
  RELEASE



  com.fasterxml.jackson.core
  jackson-core
  2.7.3


  com.fasterxml.jackson.core
  jackson-databind
  2.7.3


  org.apache.commons
  commons-lang3
  3.3.2


  javax.servlet
  javax.servlet-api
  4.0.1



  org.apache.taglibs
  taglibs-standard-spec
  1.2.5


  org.apache.taglibs
  taglibs-standard-impl
  1.2.5



  com.github.noraui
  ojdbc8
  12.2.0.1



  org.mybatis
  mybatis
  3.5.2



  org.mybatis
  mybatis-spring
  2.0.2

3. Project structure optimization

Since the new project is based on the maven template, some folders need to be added to the project structure

Create a new Java folder under main folder

Spring Framework Learning Notes (3) - Spring MVC Framework

Set Java folder to source directory

Spring Framework Learning Notes (3) - Spring MVC Framework

Create your own package name under the Java folder, and then create a new controller folder and model folder. Incidentally, create a new resource folder. Same steps as above, set it to resources directory

Spring Framework Learning Notes (3) - Spring MVC Framework

In addition, you need to create a new views folder under the webapp folder

Spring Framework Learning Notes (3) - Spring MVC Framework

4. Setting up Tomcat configuration

I have set it up here. If not, there is no drop-down menu, but there is an option to add configuration.

Spring Framework Learning Notes (3) - Spring MVC Framework

Select the settings for tomcat, select local, and if there is no option for Tomcat, click show more at the bottom of the option.

Spring Framework Learning Notes (3) - Spring MVC Framework

Click to add structure

Spring Framework Learning Notes (3) - Spring MVC Framework

Choose the exploded option

Spring Framework Learning Notes (3) - Spring MVC Framework

Set URL

Spring Framework Learning Notes (3) - Spring MVC Framework

Then start running the Web program, and you can access it.http://localhost:8080/springmvcdemoTo access the home page of a Web project

5. New Spring MVC configuration file

Spring MVC configuration file is the same as the previous spring file, which is used to configure the related beans. Because it is a resource file, we put it in the Resources folder according to the rules.

springmvc-config.xml

There is a bean class in the configuration, which is the configuration view parser (that is, the last bean tag), and we use theInternalResourceViewResolver

This parser will process the return value of the request processing class (controller class) processing method according to the format of “prefix + method return value + suffix”, and jump the processed return value as a path.

In addition, there are other parsers, which will be supplemented below.

6. Configure the web.xml file

Because we use maven’s template to create a web project, the content in web. XML is not what we need, so we have to change the content.

SpringMVC Demo

    
    
        springmvc-DispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            
            classpath:springmvc-config.xml
        
        
        1
        
        true
    
    
        springmvc-DispatcherServlet
        /

7. test

Let’s use a simple example to understand how spring MVC works

We write a controller class to simulate the implementation of login operation, login success, jump to the successful page of login.success.jsp

UserController.java

package com.wan.controller;

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

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
public class UserController {
    @RequestMapping("/https://www.cnblogs.com/kexing/p/user/login")
    public String login() {
        // Here the return is followed by a prefix and a suffix.
        // It's equivalent to jumping to views/success.jsp page
        return "success";
    }
}

success.jspThere is only one simple “Log in Successfully” text

In index. jsp, there is a link requesting URL to behttps://www.cnblogs.com/kexing/p/user/login

Sign in

Then you can jump to the page.

Spring Framework Learning Notes (3) - Spring MVC Framework

PS: The above method returns a success, which is automatically prefixed and suffixed.Here is the request forwarding

In addition, we can addforwardorredirectPrefixes for request forwarding or redirection

However, if you use these two prefixes, then the view parser will not automatically add prefixes and suffixes. So, we have to specify the URL address for the specific jump.

@RequestMapping("/https://www.cnblogs.com/kexing/p/user/login")
public String login() {
    // Request forwarding
    return "forward:/views/success.jsp";
}

@RequestMapping("/https://www.cnblogs.com/kexing/p/user/login")
public String login() {
    // redirection
    return "redirect:/views/success.jsp";
}

Request Mapping Annotation

Advanced use

The Request Mapping annotation in the spring MVC framework is not as simple as the annotation in our previous custom MVC framework. It can also annotate a class.

For example:

package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login")
    public String login() {
        // The return here is equivalent to a page jumping to views/success.jsp
        return "success";
    }
}

The URL request on our link is/https://www.cnblogs.com/kexing/p/user/loginNot to be usedlogin

Property description and use

attribute Explain
value The actual URL address of the specified request is the default attribute, such as @RequestMapping (“/login”) equivalent to @RequestMapping (value=”/login”
method Specify the method of the request, post or get
params Provide that the parameters in the request must satisfy certain conditions
header Provide that the header in the request must satisfy certain conditions

1.method

package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login",method="RequestMethod.POST")
    public String login() {
        // The return here is equivalent to a page jumping to views/success.jsp
        return "success";
    }
}

Later, if the request is not post, a 405 error will occur.

2.params

Use this property to constrain the parameters of the request

Example:

package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login",params={"name","age!=23"})
    public String login() {
        // The return here is equivalent to a page jumping to views/success.jsp
        return "success";
    }
}

The URL request parameters constrained by the above example must contain name and age, and age cannot be equal to 23. If the condition is not met, 404 errors will occur.

Such as:

Sign in

The following expressions can be received in params

Expression Explain
paramName The URL request must contain the paramName parameter name
!paramName The URL request cannot contain the paramName parameter name
paramName!=xx The URL request must contain the paramName parameter name, and the parameter value is not equal to XX

Header is less used, so it’s not added here.

Get the request URL parameter value

To get the parameter value of the URL request, we can use the RequestParam annotation

Using this annotation, you can assign the value of the URL request parameter to the method parameter

Following is a description of common attributes for the @RequestParam annotation

attribute Explain
value The parameter name for the request to carry the parameter
required Identifying the URL parameter of the request is that there must be a specific parameter, true (default): it must exist, if it does not exist, an exception will occur; false: it does not exist
defaultValue Give a default value to the method parameter, and use the default value if the request URL does not exist
package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login")
    public String login(@RequestParam(value="username") String name) {
        // The return here is equivalent to a page jumping to views/success.jsp
        return "success";
    }
}

Request URL forhttps://www.cnblogs.com/kexing/p/user/login?username=zhangThe request parameter is then assigned to the method parametername

Like our custom MVC framework, in spring MVC framework, we can also directly use entity classes, session, request, response as method parameters.

@RequestMapping("/https://www.cnblogs.com/kexing/p/user/login")
public login(Student student){
    ...
}

@RequestMapping("/https://www.cnblogs.com/kexing/p/user/login")
public login(HttpServletRequest request,HttpServletResponse response,HttpSession session){
    ...
}

AndRequestParamSimilarly, there are two.RequestHeaderandCookieValue

I haven’t used these two annotations very much now. Let’s take a look at them for a while and leave them alone.

  • RequestHeader annotation, which is mainly used to obtain the data of the request header
  • CookieValee annotation, which is mainly used to get a cookieValue

Return JSON data

We use@ResponseBodyWhen a method returns to an entity class or collection, spring MVC automatically converts us to JSON data

You need to import these two jars before you use them.jackson-core.jarandjackson-databind.jarPrevious dependencies already include the following two jars

com.fasterxml.jackson.core
  jackson-core
  2.7.3


  com.fasterxml.jackson.core
  jackson-databind
  2.7.3

UserController.java

package com.wan.controller;


import com.wan.model.Teacher;

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

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @ResponseBody
    @RequestMapping("/login")
    public Teacher login() {
        Return new Teacher ("001", "Zhang San");
    }
}

Then use ajax asynchronous requests in JSP pages

function getData() {
            $.getJSON("https://www.cnblogs.com/kexing/p/user/login", function(json){
                console.log(json);
            });
        }
    


Sign in

You can see the printed JSON data in the console

Spring Framework Learning Notes (3) - Spring MVC Framework

Processing Model Data

In Spring MVC, M actually stands for Model, which is equivalent to data.

Suppose we want to query data from data: first we send URL requests from the View, then the Controller gets the data from the database through Service/Dao, and processes the data so that the data can be sent back to the View and displayed.

If it’s an asynchronous request, we can return a JSON data to the page. If it’s not, we have to store the data in the scope of the request or session, and then the page (View) takes the data out of the scope and displays it.

Spring MVC provides four ways to handle views that need to be pulled out of scope for data display

  • ModelAndView
  • Map, ModelMap and Model
  • @SessionAttributes
  • @ModelAttribute

1.ModelAndView

This class is commonly used as the return value of a method to return a page (View) with data.

UserController.java

package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login")
    public ModelAndView login() {
        String view = "success";
        ModelAndView mav = new ModelAndView(view);
        Teacher teacher = new Teacher ("001", "Zhang San");
        // Equivalent to request. addAttribute ("teacher", teacher)
        mav.addObject("teacher",teacher);
        return mav;
    }
}

Remove data from success.jsp and display it

${requestScope.student.tno}

The example above is the same as before, or will be prefixed and suffixed to getviews/success.jsp

2. Map, ModelMap and Model

Map, ModelMap, and Model are commonly used as parameters of a method, and then data is stored in it through the put method.

package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
@RequestMapping("/user")
public class UserController {
    @RequestMapping("/login")
    public String login(Map map) {
        String view = "success";
        Teacher teacher = new Teacher ("001", "Zhang San");
        // Equivalent to request. addAttribute ("teacher", teacher)
        map.put("teacher",teacher);
        return "success";
    }
}

ModelMap and Map are used the same way

You can also use Model

@RequestMapping("/login")
    public String login(Model model) {
        String view = "success";
        Teacher teacher = new Teacher ("001", "Zhang San");
        // Equivalent to request. addAttribute ("teacher", teacher)
        model.addAttribute("teacher",teacher);
        return "success";
    }

The Model class can also use the addition of a map data.addAllAttribute(Map map)

[email protected]

The first two methods are put in the request scope. If we want to put in the session scope, we can use the @SessionAttributes annotation, which is generally labeled on the class.

@ Session Attributes can add a specified object to the session scope, or a certain type of object to the session.

The following example specifies the key as the teacher object and adds it to the session scope

package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
@RequestMapping("/user")
@SessionAttributes(value="teacher")
public class UserController {
    @RequestMapping("/login")
    public String login(Map map) {
        String view = "success";
        Teacher teacher = new Teacher ("001", "Zhang San");
        // Adding session scope as well as request scope
        map.put("teacher",teacher);
        return "success";
    }
}

Add Teacher-type objects to session scope

package com.wan.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @author StarsOne
 * @date Create in  2019/9/28 0028 14:27
 * @description
 */
@Controller
@RequestMapping("/user")
@SessionAttributes(type=Teacher.class)
public class UserController {
    @RequestMapping("/login")
    public String login(Map map) {
        String view = "success";
        Teacher teacher = new Teacher ("001", "Zhang San");
        // Adding session scope as well as request scope
        map.put("teacher",teacher);
        return "success";
    }
}

[email protected]

Usage:
We need to update the data, but we can only update one attribute of the data.

When we click on the edit, there is only one input box for us to enter to change that property. When we input the changed property value, we will find that the data in the controller and the incoming objects are null except the changed property value. We don’t want this to happen, so we use this annotation.

This annotation is used to modify a method in the controller, and then executes before executing the @RequestMapping method in the controller, updates the data in the incoming object, and then performs the modification operation, only changes the attribute values that the object needs to modify, while the other attribute values remain unchanged (not null).

Personally, I think it’s more troublesome. A better solution to the above situation is to use multiple input boxes instead of a single input box, to disable those input boxes that can’t be changed, and then submit the form and successfully pass in other attribute values.

view resolver

Workflow

In spring MVC framework, after the request processing method (method in Controller) is executed, a ModelAndView object is finally returned.

Spring MVC uses ViewResolver to get the final view object. The final view can be JSP, Excel, JFreeChart and other forms of view.

The processor does not care about which view object is used to render the model data (that is, we often say to take the data out of the scope of request and display it on the page). The processor focuses on the production of model data, so as to achieve full decoupling of MVC.

For those processing methods that return String, View or ModeMap, Spring MVC also internally assembles them into a ModelAndView object, which contains the logical name and the view of the model object.

The following picture:

Spring Framework Learning Notes (3) - Spring MVC Framework

View

View in spring MVC is actually an interface. Here are the implementation classes of the common View interface

View type Implementation class Explain
URL view type InternalResourceView Encapsulate JSP or other resources into a view. It is used by default by the view parser Internal ResourceViewResolver.
URL view type JstlView A subclass of InternalResourceView. If JSP uses JSTL’s internationalized tags, you need to use the view class
Document view AbstractExcelView The abstract class of Excel document view
Document view AbstractPdfView The abstract class of PDF document view
Report view ConfigurableJasperReportsView
Report view JasperReportsHtmlView
Report view JasperReportsPdfView
Report view JasperReportsXlsView
JSON view MappingJackson2JsonView Data is output in JSON mode through the ObjectMapper object of Jackson Framework

ViewResolver and subclasses

ViewResolver, like View, is an interface

View parser type Class name Explain
Resolve to a mapping file UrlBasedViewResolver It simply implements the ViewResolver interface and accesses resources through logical view names without any mapping
Resolve to a mapping file InternalResourceViewResolver Resolve the logical view name into a path
Resolve to beans BeanNameViewResolver Resolve the logical view name to the name attribute of the bean, so that the corresponding bean can be found according to the name attribute.
Resolve to beans ResourceBundleResolver Like BeanNameViewResolver, only the view-beans defined are in a properties file, which is used to load the properties file.
Resolve to beans XmlViewResolver Just like ResourceBundle Resolver, the view-bean defined is used to load an XML file in an XML file.
Resolve to template file VelocityViewResolver Support for Velocity Template Engine
Resolve to template file FreeMarkerViewResolver Support for FreeMarker Template Engine

Here, I will only introduce the first two types that we have used. For more information, please refer to our link below.

AbstractCachingViewResolver, which is an abstract class, implements the ViewResolver interface. The abstract class can only be inherited and cannot create instances.

UrlBasedViewResolver extends functionality by inheriting from AbstractCachingViewResolver.

AbstractCaching ViewResolver introduces:

This view parser saves the views it has parsed, and then looks in the cache every time it parses the view.

If the corresponding view is found, it will be returned directly. If not, a new view object will be created. Then it will be put into a map for caching, and then the new view will be returned.

Using this view caching approach can minimize the performance problems of parsing views.

UrlBasedViewResolver introduces:

It inherits AbstractCaching ViewResolver, which mainly provides a way to parse views by splicing URLs, so that we can pass through it.prefixProperty specifies a specified prefix throughsuffixProperty specifies a specified suffix, and then the returned logical view name with the specified prefix and suffix is the specified view URL.

Introduced by International Resource View Resolver:

This class is inherited from UrlBasedViewResolver, which has both functions and its own features. In literal translation, the Internal ResourceViewResolver is the internal resource resolver.

The Internal ResourceViewResolver resolves the returned view names into the Internal ResourceView objects, and the Internal ResourceView stores the model attributes returned by the Controller processor methods into the corresponding request attributes, and then redirects the request for word to the target URL on the server side through the Request Dispatcher.

Reference link: Spring MVC – Start from scratch – View – ViewResolver

Static resource access

scene

If we want to access a picture, JS file, video and other static resources in our project through a url, we will find a 404 error.

The reason is that we define a pre-Servlet that handles all URL requests, but because we can’t find the matching URL on the RequestMapping annotation, a 404 error occurs.

Resolvent

Add in Spring MVC configuration fileandIt can solve the problem.

In the springmvc configuration file given earlier, these two tags have actually been added. Here’s a brief introduction of the role

Role: In the Spring MVC context, a Default Servlet HttpRequestHandler is defined, which checks requests processed by @Dispatcher Servlet. If a request is not processed by @RequestMapping, the request is handed over to the default Servlet of the Web server for processing. The default Servlet accesses the resource directly according to the url.

Function: While accessing static resources, the eye can normally access other non-static resources.

Both tags need to be added

Chinese garbled method (Supplement)

1. setting page encoding

2. Configuring filters

Configuration in web.xml

SpringMVC Demo

    
    
        characterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            UTF-8
        
        
            forceEncoding
            true
        
    
    
        characterEncodingFilter
        /
    
    
    
    
        springmvc-DispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            
            classpath:springmvc-config.xml
        
        
        1
        
        true
    
    
        springmvc-DispatcherServlet
        /

For more information, see the reference link

Reference link: thoroughly solve springMVC Chinese garbled code