Personal java learning route-SpringMVC

SpringMVC

1. Spring MVC

introduce

  1. Review MVC
    M: model model (dao, service)
    V: view view (jsp)
    C: controller controller (Servlet)

  2. MVVM
    M: model model (dao, service)
    V: view view (jsp)
    VM: ViewModel: two-way binding (the core of front-end and back-end separation)

  3. Spring
    We can register all the beans to be used in SpringMVC into Spring!

  4. SpringMVC

  • Spring MVC is part of the Spring Framework and is a lightweight web framework based on Java to implement MVC
  • Spring's web framework is designed around DispatcherServlet, and the role of DispatcherServlet is to distribute requests to different processors.
  • Like many other MVC frameworks, the Spring MVC framework is request-driven, dispatching requests and providing other functions around a central Servlet. DispatcherServlet is an actual Servlet (inherited from HttpServlet)
  • Three major pieces that SpringMVC must configure:
    processor mapper, processor adapter, view resolver

rely

<dependency>
	<groupId>org.springframework</groupId>
		<artifactId>spring-webmvc</artifactId>
	<version>5.3.9</version>
</dependency>

Two, first Spring MVC

After using springmvc, we can simplify many places when dealing with page and background interaction.

1. First look at the dependencies

<dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.9</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

Don't forget to add output configuration when using idea

<build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

2. Define DispatcherServlet

ps: springmvc-servlet.xml needs to be created

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

    <!--1.注册DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件:【servlet-name】-servlet.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--启动级别-1-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!--    / 匹配所有的请求:(不包括.jsp)-->
    <!--    /* 匹配所有的请求:(包括.jsp)-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

3. Create a Spring MVC configuration file (custom 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 http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--添加处理映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <!--添加处理器适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
    <!--
        添加视图解析器: DispatcherServlet给他的ModelAndView
        1.获取了ModelAndView的数据
        2.解析了ModelAndView的视图名字
        3.拼接视图名子,找到对应的视图 hello
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!--后缀-->
        <property name="suffix" value=".jsp" />
    </bean>
    

</beans>

4. Create Controller

Create your own package /com/person/controller under the java of src, and then create the file FirstController

public class FirstController implements Controller {
    
    

    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        //ModelAndView 模型和视图
        ModelAndView mv=new ModelAndView();

        //封装对象,放在ModelAndView中。Model、
        mv.addObject("msg","HelloSpringMVC");
        //封装要跳转的视图,放在ModelAndView中
        mv.setViewName("hello");//  : /WEB-INF/jsp/hello.jsp
        return mv;
    }
}

At this time, remember to go back to springmvc-servlet.xml and add configuration

    <!--Handler-->
    <bean id="/hello" class="com.person.controller.FirstController"/>

At this point, the complete springmvc-servlet.xml should be (anti-forgetting)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--添加处理映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
    <!--添加处理器适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter" />
    <!--
        添加视图解析器: DispatcherServlet给他的ModelAndView
        1.获取了ModelAndView的数据
        2.解析了ModelAndView的视图名字
        3.拼接视图名子,找到对应的视图 hello
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/" />
        <!--后缀-->
        <property name="suffix" value=".jsp" />
    </bean>

    <!--Handler-->
    <bean id="/hello" class="com.person.controller.FirstController"/>
</beans>

5. Create View

Create /jsp/hello.jsp under "WEB-INF"

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

6. Deployment view

Just add /hello after the page that is automatically opened after deployment
insert image description here

Three, controller annotation

The controller class uses annotations

Not required when using annotations

    <!--Handler-->
    <bean id="/hello" class="com.person.controller.FirstController"/>

Change the class of the controller package to

@Controller
@RequestMapping("/hello")
public class HelloController v{
    
    
    @RequestMapping("/h1")
    public String hello(Model model){
    
    
        //  封装数据
        model.addAttribute("msg","AnnotationTest信息");
        return "hello";//会被视图解析器处理
    }
}

That's it.
The corresponding springmvc-servlet.xml can be modified to

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/mvc
                           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->
    <context:component-scan base-package="com.person.controller" />
    <!--让Spring MVC不处理静态资源-->
    <mvc:default-servlet-handler />
    <!--
        支持mvc注解的驱动
            在Spring中一般采用@RequestMapping注解来完成映射关系
            要想使@RequestMapping注解生效
            必须向上下文中注册DefaultAnnotationHandlerMapping
            和一个AnnotationMethodHandlerAdapter实例
            这两个实例分别在类级别和方法级别处理
            而annotation-driven配置帮助我们自动完成上述两个实例的注入

    -->
    <mvc:annotation-driven />

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

The URL of the webpage access hello method
is: http://localhost:3306/project address/hello/h1

@Controller annotation

  • The @Controller annotation type is used to declare that the instance of the Spring class is a controller (I also learned three other annotations during IOC: @Component, @Service, @Repository)

      @Component      组件
      @Service        service
      @Controller     controller
      @Repository     dao
    

Fourth, the controller Controller

  • The controller provides complex access to the behavior of the application, usually through interface definition or annotation definition.
  • The controller is responsible for parsing the user's request and converting it into a model
  • A controller class in Spring MVC can contain multiple methods
  • In Spring MVC, there are many ways to configure Controller

Controller configuration method: the first method

不需要配置自动扫描包,不处理映射文件,mvc注解驱动(处理器映射器,处理器适配器):
   <context:component-scan base-package="com.person.controller" />
   <mvc:default-servlet-handler />
   <mvc:annotation-driven />
  • The complete code is as follows:
    web.xml:
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

spring-servlet.xml——springmvc configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

    <bean name="/t1" class="com.person.controller.ControllerTest1"/>

</beans>

Controller class:

//只要实现类Controller接口的类,说明这就是一个控制器
public class ControllerTest1 implements Controller {
    
    
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        ModelAndView mv = new ModelAndView();
         mv.addObject("msg","ControllerTest1");
         mv.setViewName("test");
        return mv;
    }
}

View:

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

Web page search after deployment: prefix /t1 (see spring-servlet.xml bean)

Controller configuration method: the second method

Use the @Controller annotation on the class

@Controller//代表这个类会被Spring接管,被这个注解的类中的所有方法,如果返回值为String,并且有具体的类可以跳转,那么就会被视图解析器解析
public class ControllerTest2 {
    
    
    @RequestMapping("/t2")
    public String test1(Model model){
    
    
        model.addAttribute("msg","ControllerTest2");
        return "test";//这里表示会去找/WEB-INF/jsp/test.jsp文件
    }

    @RequestMapping("/t3")
    public String test2(Model model){
    
    
        model.addAttribute("msg","test3");
        return "test";//这里表示会去找/WEB-INF/jsp/test.jsp文件
    }
}

Then just add the scan package to spring-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"
       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">
                           
     <!--自动扫描包,让指定包下的注解生效,由IOC容器统一管理-->                      
    <context:component-scan base-package="com.person.controller" />

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

Web page search after deployment:
http://localhost:3306/project address/t2
http://localhost:3306/project address/t3
It can be seen that multiple requests can point to the same view, but the page output results are different, from It can be seen here that the view is reused, and there is a weak coupling relationship between the controller and the view

The second method extends

Using the second method, it can be seen that multiple methods can be written in ControllerTest2
and further operations on the url can also be performed

@Controller
@RequestMapping("/c3")
public class ControllerTest3 {
    
    
    @RequestMapping("/t1")
    public String test3(Model model){
    
    
        model.addAttribute("msg","测试三");
        return "test";
    }
}

At this time, after redeployment, search on the webpage:
http://localhost:3306/project address/c3/t1

5. RestFul style

Concept:
Restful is a style of resource location and resource operation, not a standard/protocol, but a style

For example:
Original URL: http://localhost:3306?item=xxx&id=sss
After using this style: http://localhost:3306/item/xxx/id/sss

Operate resources in the traditional way: achieve different effects through different parameters! Single method, post and get
RESTFul operation resources: different effects can be achieved through different request methods! (The request address is the same, but the function can be different) (GET POST PUT DELETE)

comparison test

1. before

@Controller
public class RestFulController {
    
    
    @RequestMapping("/add")
    public String test(int a,int b,Model model){
    
    
        model.addAttribute("msg","结果为"+(a+b));
        return "test";
    }
}

Webpage input: http://localhost:9527/add?a=1&b=2
The output result is 3
2. Now RestFul

Use the @PathVariable annotation in Spring to bind the value of the method parameter to a URL template variable

@Controller
public class RestFulController {
    
    
    @RequestMapping("/add/{a}/{b}")
    public String test(@PathVariable int a,@PathVariable int b, Model model){
    
    
        model.addAttribute("msg","结果为"+(a+b));
        return "test";
    }
}

URL: http://localhost:9527/add/1/2
The output result is 3

RestFul request method method

In the RestFul style, if the submission method of the front-end web page does not match the back-end, an exception will occur

 @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.DELETE)

ps: here value can be replaced by path (name cannot be used, name is the name of mapping, value and path are aliases for each other)

You can also use the label corresponding to the request method:

@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
@RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.DELETE)
@DeleteMapping("/add/{a}/{b}")
@GetMapping("/add/{a}/{b}")
@Controller
public class RestFulController {
    
    
//    @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.GET)
//    @RequestMapping(value = "/add/{a}/{b}",method = RequestMethod.DELETE)
//    @GetMapping("/add/{a}/{b}")
//    @DeleteMapping("/add/{a}/{b}")
    @PostMapping("/add/{a}/{b}")
    public String test(@PathVariable int a,@PathVariable int b, Model model){
    
    
        model.addAttribute("msg","POST方法请求结果为"+(a+b));
        return "test";
    }

    @GetMapping("/add/{a}/{b}")
    public String test2(@PathVariable int a,@PathVariable int b, Model model){
    
    
        model.addAttribute("msg","GET方法返回结果为"+(a+b));
        return "test";
    }
}

Six, jump

After setting the ModelAndView object

Page: {view resolver prefix} + viewName + {view resolver suffix}

ServletAPI

By setting the ServletAPI, we don't need a view resolver

  • 1. Output through HttpServletResponse
  • 2. Realize redirection through HttpServletResponse
  • 3. Forwarding through HttpServletResponse

Servlet redirection

Use the above 'four, controller Controller' template in the second way

@Controller
public class ModelTest1 {
    
    
    @RequestMapping("/m1/t1")
    public String test(HttpServletRequest request, HttpServletResponse response){
    
    
        HttpSession session = request.getSession();
        System.out.println(session.getId());
        return "test";
    }
}

You can use jump redirection in HttpServlet (requires view resolver)

Forwarding and redirecting with Spring MVC - no need for a view resolver

Remove the view resolver in spring-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"
       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">


    <context:component-scan base-package="com.person.controller" />
</beans>

Test instance:

@Controller
public class ModelTest1 {
    
    

    @RequestMapping("/m1/t1")
    public String test(HttpServletRequest request, HttpServletResponse response){
    
    

        HttpSession session = request.getSession();
        System.out.println(session.getId());

        return "test";
    }

    @RequestMapping("/m2/t1")
    public String test1(){
    
    
        //跳转
        return "/jumpTest.jsp";
    }

    @RequestMapping("/m2/t2")
    public String test2(){
    
    
        //跳转
        return "forward:/WEB-INF/jsp/test.jsp";
    }

    @RequestMapping("/m2/t3")
    public String test3(){
    
    
        //重定向
        return "redirect:/WEB-INF/jsp/test.jsp";
    }
}

Seven, processing submitted data

1. The submitted domain name is consistent with the parameter name of the processing method

Submit data: http://localhost:9527/t1?name=lisi

public class ModelTest1 {
    
    
    @RequestMapping("/t1")
    public String test1(String name, Model model){
    
    
        //1.接受前端参数
        System.out.println("接收到前端的参数为:"+name);
        //2.将返回的结果传递给前端
        model.addAttribute("msg",name);
        return "test";
    }
}

Background output: lisi

2. The submitted domain name is inconsistent with the parameter name of the processing method

Use @RequestParam("username") to annotate method parameters
Submit data: http://localhost:9527/t2?username=lisi

@Controller
public class ModelTest1 {
    
    
    @RequestMapping("/t2")
    public String test2(@RequestParam("username") String name, Model model){
    
    
        //1.接受前端参数
        System.out.println("接收到前端的参数为:"+name);
        //2.将返回的结果传递给前端
        model.addAttribute("msg",name);
        return "test";
    }
}

Background output: lisi

3. What is submitted is an object

Submit data: http://localhost:9527/t3?id=1&name=lisi&age=18

@Controller
public class ModelTest1 {
    
    
    //前端接收的是一个对象
    /*
     1.接受前端用户传递的参数,判断参数的名字,假设名字直接在方法上,可以直接使用
     2.假设传递的是一个对象User,匹配User对象中的字段名,如果名字一致则OK,否则,匹配不到
     */
    @RequestMapping("/t3")
    public String test3(User user){
    
    
        System.out.println(user);
        return "test";
    }
}

Background output: User(id=1, name=lisi, age=18)

If the parameter name submitted by the front end does not match the attribute name of the class
Front end: http://localhost:9527/t3?id=1&username=lisi&age=18
Backend output: User(id=1, name=null, age=18)

Eight, data display to the front end

The first: through ModelAndView

method at the beginning

public class HelloController implements Controller {
    
    
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
    
    
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","SecondHello");
        mv.setViewName("testJsp");
        return mv;
    }
}

The second type: through ModelMap

Inherited LinkedMap, Model is a simplified version of ModelMap, mainly uses Model, and ModelMap is currently used in the same way as Model

The third way: through Model

Example of the second way above:

@Controller
public class ModelTest1 {
    
    
    @RequestMapping("/t2")
    public String test2(@RequestParam("username") String name, Model model){
    
    
        //1.接受前端参数
        System.out.println("接收到前端的参数为:"+name);
        //2.将返回的结果传递给前端
        model.addAttribute("msg",name);
        return "test";
    }
}

Comparison of the three

Model has only a few methods that are suitable for storing data, which simplifies the operation and understanding of Model objects for novices.
ModelMap inherits LinkedMap. In addition to implementing some methods of its own, the same methods and characteristics inherited from LinkedMap.
ModelAndView can store data. You can set the returned logical view to control the jump of the presentation layer

Nine, garbled characters

example

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

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

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


    <context:component-scan base-package="com.person.controller" />

    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>
</beans>

controller:

@Controller
public class ModelTest1 {
    
    

    @PostMapping("/t1")
    public String test1(String name, Model model){
    
    
        System.out.println(name);
        model.addAttribute("msg",name);
        return "test";
    }
}

Front-end page (same level as index.jsp)

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/t1" method="post">
    <input type="text" name="name">
    <input type="submit" value="提交按钮">
</form>
</body>
</html>

Front-end page test.jsp (under /WEB-INF/jsp/)

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

test

Test instruction

Enter "invincible" in the jsp page form

After submitting to Controller

Console output: ???

Echo to the web page "æ— æ•Œ"

It can be seen that when java gets the page submission data, it is already garbled

Solution 1 - write a filter yourself

Create EncodingFilter class under com.person.filter package

public class EncodingFilter implements Filter {
    
    
    public void init(FilterConfig filterConfig) throws ServletException {
    
    

    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
    
        request.setCharacterEncoding("utf-8");
        request.setCharacterEncoding("utf-8");
        chain.doFilter(request,response);
    }

    public void destroy() {
    
    

    }
}

Go to web.xml to configure the filter

    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>com.person.filter.EncodingFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

Test again without error

Note: <url-pattern>/*</url-pattern>, to filter all pages including jsp, use /* instead of /

Solution 2 - use SpringMVC's garbled filter

Just configure it directly

<filter>
    <filter-name>encoding</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
        <param-name>encoding</param-name>
        <param-value>utf-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

universal solution

解决网页传送数据给java乱码的万能解决方法:
因为网页传送数据是ISO-8859-1,把这个转化成中文就行
byte[] bytes=name.getBytes("ISO-8859-1");
name=new String(bytes,"UTF-8");

10. JSON

  • Now is the era of front-end and back-end separation

The backend deploys the backend, provides interfaces, and provides data:

The front-end is deployed independently and is responsible for rendering the data of the back-end:

The most commonly used JSON data format for front-end and back-end data transmission

Java generates json object

Maven imports JSON processor jar package

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.11.0</version>
</dependency>

Processing with jar package

public class A{
    
    
 @RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")
    @ResponseBody//标注该注解就不会走视图解析器,会直接返回一个字符串
    public String json1(){
    
    

        //jackson. ObjectMapper
        ObjectMapper mapper=new ObjectMapper();

        //创建对象
        User user=new User(1,"王二",18);
        String str=null;
        try {
    
    
            str=mapper.writeValueAsString(user);
        } catch (JsonProcessingException e) {
    
    
            e.printStackTrace();
        }
        return str;
    }
}

@RestController is used on the class, and the annotation will not go through the view parser, and will directly return a string instead of @Controlle

@ResponseBody is used on the method, and the annotation will not go through the view parser, and will directly return a string, which can be used with @Controlle

Produces are used to deal with garbled characters

Garbled processing

The encoding can be specified uniformly through the spring configuration.
Add a message StringHttpMessageConverter conversion configuration in springmvc

<!--解决乱码问题-->
<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>

FastJson.jar

fastjson.jar is a package developed by Ali for Java development. It can easily realize the conversion of json objects and JavaBean objects,
realize the conversion of JavaBean objects and json strings, and realize the conversion of json objects and json strings.

Three main classes of fastjson:

  • JSONObject represents the json object
  • JSONArray represents an array of json objects
  • JSON represents the conversion of JSONObject and JSONArray

Guide package

<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.75</version>
</dependency>

Eleven, springmvc interceptor

The difference between filter and interceptor: interceptor is the specific application of AOP thought

filter:

  • Part of the servlet specification, any java web project can use
  • After configuring /* in url-pattern, all resources to be accessed can be intercepted

Interceptor:

  • The interceptor is the SpringMVC framework itself, and only projects that use the SpringMVC framework can use it
  • The interceptor will only intercept the accessed controller method, if the access is jsp/html/css/image/js it will not be intercepted

A brief introduction to interceptors

We can implement the HandlerInterceptor interface to write our own interceptors

public class MyInterceptor implements HandlerInterceptor {
    
    
    //return true;执行下一个拦截器,放行
    //return false;不执行下一个拦截器
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    
    
        System.out.println("=======处理前======");
        return true;
    }

    //后面两个类似于日志
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
    
        //System.out.println("========处理后======");
    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
    
        //System.out.println("======清理======");
    }
}

Then configure the interceptor in applicationContext.xml

<!--拦截器配置-->
<mvc:interceptors>
    <mvc:interceptor>
        <!--包括这个请求下面的所有的请求-->
        <mvc:mapping path="/**"/>
        <bean class="com.person.config.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

12. File upload and download

Introduction to core process

1. Configure jar

<dependencies>
    <!--文件上传-->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.3</version>
    </dependency>
    <!--高版本的servlet-api-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>4.0.1</version>
    </dependency>
</dependencies>

2. Front-end html

<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
  <input type="file" name="file"/>
  <input type="submit" value="upload"/>
</form>

3.applicationContext.xml deployment

<!--文件上传配置-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!--请求编码格式,必须和jsp的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1-->
    <property name="defaultEncoding" value="utf-8"/>
    <!--上传文件大小上限,单位为字节-->
    <property name="maxUploadSize" value="10485760"/>
    <property name="maxInMemorySize" value="40960"/>
</bean>

4 write fileController.java

full example

pom.xml import dependencies

    <dependencies>
        <!--文件上传-->
        <dependency>
            <groupId>commons-fileupload</groupId>
            <artifactId>commons-fileupload</artifactId>
            <version>1.3.3</version>
        </dependency>
        <!--高版本的servlet-api-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
        </dependency>
    </dependencies>

web.xml

    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

applicationContext.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
                           http://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
                           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <context:component-scan base-package="com.person.controller"/>
    <mvc:default-servlet-handler /><!--静态资源过滤,类似jQuery之类的静态资源导入必须要用-->
    <mvc:annotation-driven/>

    <!--解决JSON乱码问题配置    -->
    <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>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
          id="internalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

    <!--文件上传配置-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <!--请求编码格式,必须和jsp的pageEncoding属性一致,以便正确读取表单的内容,默认为ISO-8859-1-->
        <property name="defaultEncoding" value="utf-8"/>
        <!--上传文件大小上限,单位为字节-->
        <property name="maxUploadSize" value="10485760"/>
        <property name="maxInMemorySize" value="40960"/>
    </bean>
</beans>

Create the FileController class under the java.com.person.controller package

@RestController
public class FileController {
    
    

//  @RequestParam("file")将name=file控件得到的文件封装成CommonsMultipartFile对象
//  批量上传CommonsMultipartFile则为数组即可
    @RequestMapping("/upload")
    public String fileUpload(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
    
    
        //获取文件名:file.getOriginalFilename();
        String uploadFileName=file.getOriginalFilename();

        //如果文件名为空,则返回首页
        if("".equals(uploadFileName)){
    
    
            return "redirect:/index.jsp";
        }
        System.out.println("上传文件名:"+uploadFileName);

        //上传路径保存设置
        String path=request.getServletContext().getRealPath("/upload");
        //如果路径不存在,创建一个
        File realPath=new File(path);
        if(!realPath.exists()){
    
    
            realPath.mkdir();
        }
        System.out.println("上传文件保存地址:"+realPath);

        InputStream is=file.getInputStream();//文件输入流
        OutputStream os=new FileOutputStream(new File(realPath,uploadFileName));//文件输出流

        //读取写出
        int len=0;
        byte[] buffer=new byte[1024];
        while ((len=is.read(buffer))!=-1){
    
    
            os.write(buffer,0,len);
            os.flush();
        }
        os.close();
        is.close();
        return "redirect:/index.jsp";
   }

   /*
        采用file.Transto来保存上传的文件
    */
   @RequestMapping("/upload2")
   public String fileUpload2(@RequestParam("file") CommonsMultipartFile file, HttpServletRequest request) throws IOException {
    
    
       //上传路径保存配置
       String path=request.getServletContext().getRealPath("/upload");
       File realPath=new File(path);
       if(!realPath.exists()){
    
    
           realPath.mkdir();
       }

       //上传文件地址
       System.out.println("上传文件保存地址:"+realPath);

       //通过CommonsMultipartFile的方法直接写文件(注意这个时候)
       file.transferTo(new File(realPath+"/"+file.getOriginalFilename()));

       return "redirect:/index.jsp";
   }



    @RequestMapping("/download")
    public String downloads(HttpServletResponse response,HttpServletRequest request) throws IOException {
    
    
       //要下载的图片地址
        String path=request.getServletContext().getRealPath("/upload");
        String fileName="1.png";

        //1.设置response 响应头
        response.reset();//设置页面不缓存,清空buffer
        request.setCharacterEncoding("UTF-8");//字符编码
        response.setContentType("multipart/form-data");//二进制传输数据
        //设置响应头
        response.setHeader("Content-Disposition","attachment;fileName="+ URLEncoder.encode(fileName,"UTF-8"));
        File file=new File(path,fileName);
        //2.读取文件--输入流
        InputStream input=new FileInputStream(file);
        //3.写出文件--输入流
        OutputStream out=response.getOutputStream();

        byte[] buffer=new byte[1024];
        int index=0;
        while ((index=input.read(buffer))!=-1){
    
    
            out.write(buffer,0,index);
            out.flush();
        }
        out.close();
        input.close();
        return null;
    }
}

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
  <head>
    <title>$Title$</title>
  </head>
  <body>
<form action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data" method="post">
  <input type="file" name="file"/>
  <input type="submit" value="upload"/>
</form>
  </body>
</html>

Let me mention the test here.
After the code is deployed, the uploaded file on the homepage can be seen in the out output. The
download must also be the out/upload/1.png file before it can be downloaded using /download
insert image description here

After the project is created, if the webpage cannot be opened, look here first! !

Idea needs to manually create the lib package (dependency)
insert image description here
insert image description here
application. It should be noted that
the above steps must be repeated each time a new dependency is added, otherwise the dependency will not take effect

Guess you like

Origin blog.csdn.net/youxizaixian123/article/details/121054313