自学SSM之SpringMVC

1、SpringMVC

什么是springmvc?

之前我们在学servlet的时候,有了解过mvc设计模式:

  • M: model,对应着dao、service层

  • V:view,对应着jsp层

  • C:controller,对应着servlet层

Spring 框架提供了构建 web应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架

2、回顾servlet(简单回顾)

  1. 导入依赖包

    1. 父工程
    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.ryan</groupId>
        <artifactId>SpringMVC-study</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>springmvc-servlet</module>
        </modules>
    
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.6.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
        </dependencies>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <!--修改Language level-->
            <maven.compiler.source>11</maven.compiler.source>
            <!--修改Java Compiler-->
            <maven.compiler.target>11</maven.compiler.target>
        </properties>
    </project>
    
    1. 子模块
        <dependencies>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.2</version>
            </dependency>
        </dependencies>
    
  2. 配置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>hello</servlet-name>
            <servlet-class>com.ryan.controller.HelloServlet</servlet-class>
        </servlet>
        <servlet-mapping>
            <servlet-name>hello</servlet-name>
            <url-pattern>/hello</url-pattern>
        </servlet-mapping>
    </web-app>
    
  3. 编写model层:略

  4. 编写view层:

    1. 表单

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

      <%@ page contentType="text/html;charset=UTF-8" language="java" %>
      <html>
      <head>
          <title>hello</title>
      </head>
      <body>
      ${msg}
      </body>
      </html>
      
  5. 编写controller层

    package com.ryan.controller;
    
    import java.io.IOException;
    
    public class HelloServlet extends javax.servlet.http.HttpServlet {
        protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
    
            String method = request.getParameter("method");
            if(method.equals("add")){
                request.setAttribute("msg", "执行了" + method + "方法");
            }
            if (method.equals("delete")){
                request.setAttribute("msg", "执行了" + method + "方法");
            }
            request.getRequestDispatcher("/WEB-INF/jsp/hello.jsp").forward(request, response);
    
        }
    
        protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, IOException {
            this.doPost(request,response);
        }
    }
    
    

小结:mvc框架要做哪些事情

  1. 将url映射到java类或java类的方法
  2. 封装用户提交的数据
  3. 处理请求-调用相关的业务处理-封装响应数据
  4. 将响应的数据进行渲染.jsp/html等表示层数据

3、HelloSpringMVC

方式一:原生态,原理讲解

  1. 新建一个module,导入依赖

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.2.6.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
        </dependency>
    </dependencies>
    
  2. 配置web.xml,配置DispatcherServlet,并关联spring配置文件

    <?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">
    
        <!--配置dispatcherServlet:这个时springmvc的核心:请求分发器,前端控制器-->
        <servlet>
            <servlet-name>SpringMVC</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <!--DispatcherServlet要绑定那个spring配置文件-->
            <init-param>
                <param-name>contextConfigLocation</param-name>
                <param-value>classpath:springmvc-servlet.xml</param-value>
            </init-param>
            <!--启动等级-->
            <load-on-startup>1</load-on-startup>
        </servlet>
    
        <!--springmvc中的/和/*
            /:只匹配所有的请求,不会去匹配jsp页面
            /*:匹配所有的请求,包括jsp页面
    
            这样所有的请求都会走上面的servlet
        -->
        <servlet-mapping>
            <servlet-name>SpringMVC</servlet-name>
            <url-pattern>/</url-pattern>
        </servlet-mapping>
    
    </web-app>
    
  3. 编写SpringMVC的配置文件:springmvc-servlet.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd">
    
        <!--Dispatcher处理器映射器-->
        <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
        <!--处理器适配器-->
        <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
        <!--view视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
            <!--前缀-->
            <property name="prefix" value="/WEB-INF/jsp/"/>
            <!--后缀-->
            <property name="suffix" value=".jsp"/>
        </bean>
    
        <!--这里的id就相当于虚拟路径+跳转页面名称了-->
        <bean id="/hello" class="com.ryan.controller"/>
    </beans>
    
  4. 编写controller实体类,需继承Controller,最后注入到spring容器中

    package com.ryan;
    
    import org.springframework.web.servlet.ModelAndView;
    import org.springframework.web.servlet.mvc.Controller;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class controller implements Controller {
        @Override
        public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
            ModelAndView mv = new ModelAndView();
            //业务逻辑
            String msg = "HelloSpringMVC";
            mv.addObject("msg",msg);
            //视图跳转
            mv.setViewName("hello");
            return mv;
        }
    }
    
  5. 启动tomcat,跳转到hello页面

测试前请注意两点:

  • 确保依赖已导入
    在这里插入图片描述
  • 确保lib已经导入相关jar包(可能会出现这样的问题)
    在这里插入图片描述
    总结:
  1. 首先用户发起请求,通过DispatcherServlet
  2. BeanNameUrlHandlerMapping处理器找到url的id(/hello),并返回给DispatcherServlet
  3. DispatcherServlet携带结果通过适配器找到相对应的Controller(com.ryan.controller)
  4. com.ryan.controller执行相关业务操作后,最终将视图返回给DispatcherServlet
  5. DispatcherServlet再通过视图解析器跳转到客户请求的页面

以上可以参考下面的流程图来看, 总共可以分为处理器、适配器、解析器三部分

当然这里只是为了理解其中的原理,实际开发不会这么复杂的
在这里插入图片描述

方式二:注解+配置,简化代码

  1. 新建一个module,确保依赖和lib目录都已经导入

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.ryan</groupId>
        <artifactId>SpringMVC-study</artifactId>
        <packaging>pom</packaging>
        <version>1.0-SNAPSHOT</version>
        <modules>
            <module>springmvc-servlet</module>
            <module>spring-01-hellomvc</module>
            <module>spring-02-HelloSpringMVC</module>
        </modules>
    
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.13</version>
            </dependency>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-webmvc</artifactId>
                <version>5.2.6.RELEASE</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>jstl</artifactId>
                <version>1.2</version>
            </dependency>
            <dependency>
                <groupId>javax.servlet</groupId>
                <artifactId>servlet-api</artifactId>
                <version>2.5</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/javax.servlet.jsp/jsp-api -->
            <dependency>
                <groupId>javax.servlet.jsp</groupId>
                <artifactId>jsp-api</artifactId>
                <version>2.2</version>
            </dependency>
        </dependencies>
    
        <build>
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                        <include>**/*.properties</include>
                    </includes>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.xml</include>
                        <include>**/*.properties</include>
                    </includes>
                </resource>
            </resources>
        </build>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <!--修改Language level-->
            <maven.compiler.source>11</maven.compiler.source>
            <!--修改Java Compiler-->
            <maven.compiler.target>11</maven.compiler.target>
        </properties>
    </project>
    
  2. 配置web.xml文件

    • 注册DispatcherServlet
    • 关联SpringMVC配置文件
    • 设置启动等级为1
    • 配置映射路径
    <?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">
    
        <!--注册DispatcherServlet-->
        <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:springmvc-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>
    
  3. 配置SpringMVC的配置文件,对比前面的,处理器映射器和Controller适配器都不需要写了,都交给controller类中使用注解配置

    • 让IOC的注解生效(component-scan)
    • 让SpringMVC不处理静态资源(譬如js css html等资源)
    • MVC的注解驱动
    • 配置视图解析器
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <!--自动扫描,让指定包下的注解生效,并由IOC容器统一管理-->
        <context:component-scan base-package="com.ryan.controller"/>
        <!--过滤静态资源-->
        <mvc:default-servlet-handler/>
        <!--mvc注解驱动,替代了之前的处理器和适配器-->
        <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>
    
  4. 编写controller类,类上注解@Controller,方法上注解@RequestMapping(“访问路径”)

    package com.ryan.controller;
    
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller//相当于之前的实现Controller接口,且等价于component
    public class HelloController {
        @RequestMapping("/hello")//真实访问路径,比如这里写/hi,那么在地址栏上输入/hi
        public String hello(Model model){
            model.addAttribute("msg", "HelloSpringMVC");
            return "hello";
        }
    }
    
    
  5. 最后开启tomcat,测试执行

注意:

  • springmvc配置文件中开启了component扫描,@controller等价于@component(不同的层名字不同)
  • mvc:annotation-driven/这个会自动开启映射器处理器和controller适配器
  • @Controller相当于实现Controller接口
  • @RequestMapping("/hello"),是映射客户访问的真实路径

@Controller详解

  • 使用它标记的类就是一个SpringMVC Controller 对象
  • 分发处理器将会扫描使用了该注解的类的方法,并检测该方法是否使用了@RequestMapping 注解。
  • @Controller 只是定义了一个控制器类,而使用@RequestMapping 注解的方法才是真正处理请求的处理器

@RequestMapping详解

  • 该注解用于映射url到控制器类或一个特定的处理程序方法,可用于类或方法上,用于类上,表示类中的所有响应请求的方法都是以该地址为父路径,例如

    @Controller
    @RequestMapping("/admin")
    public class HelloController {
        @RequestMapping("/hello")
        public String hello(Model model){
            model.addAttribute("msg", "HelloSpringMVC");
            return "hello";
        }
    }
    //则如果你想要访问到hello,路径是这样的:localhost:8080/admin/hello
    

总结:

  • 相比servlet,代码精简了非常多
  • 如果想要跳转多个页面,在controller类中多写几个方法并配置对应的访问路径即可,一个视图可以得到复用,不需要像以前那样写多个servlet,这种非常简单的操作,有点接近于实际开发中的操作了
  • 操作简单了,但是你要知道他底层的实现原理,这是面试过程中和hr的谈资

4、RestFul风格

什么是restful风格?

RestFul就是一个资源定位及资源操作的风格,不是标准也不是协议,只是一种风格,基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存等机制

功能

  • 资源:互联网所有的事物都可以被抽象为资源
  • 资源操作:使用POST 、DELETE、PUT、GET,使用不同的方法对资源进行操作
  • 分别对应添加、删除、修改、查询,用得比较多的都是post和get

传统方式操作资源:通过不同的参数来实现不同的效果,方法单一

使用RestFul操作资源:可以通过不同的请求方式来实现不同的效果,甚至请求地址完全一样,也可以实现不同的功能

使用:

  1. 创建一个模块,确保依赖和lib已经导入

  2. 配置web.xml和springmvc-servlet.xml

  3. 编写controller类,使用注解

    package com.ryan.RestFulController;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.Model;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    public class RestFulController {
        @RequestMapping("/test")
        public String test1(Model model){
            model.addAttribute("msg", "restful");
            return "test";
        }
        /*
            在传统的传参风格中是这样的:localhost:8080/test?a=1&b=2
            而我们经常看到的大多是这样的:localhost:8080/test/1/2,这种就是restful风格的,具体怎么实现呢?
            在参数添加@PathVariable,然后再从映射路径中接收参数
            我们还可以改变注解规定其访问提交数据的方式
         */
        //@RequestMapping("/test/{a}/{b}")
        @GetMapping("/test/{a}/{b}")//此时通过post方式是访问不到这个的
        public String test2(@PathVariable int a, @PathVariable int b, Model model){
            int res = a + b;
            model.addAttribute("msg", "get结果=" + res);
            return "test";
        }
    
        @PostMapping("/test/{a}/{b}")//只有通过Post方式才能访问到
        public String test3(@PathVariable int a, @PathVariable int b, Model model){
            int res = a + b;
            model.addAttribute("msg", "post结果=" + res);
            return "test";
        }
    
        /*
            此时你会发现当test2和test3的访问路径可以完全一样:http://localhost:8080/test/1/2
            但是通过不同的访问方式,会有不同的结果
            通过get方式:get结果=3
            通过post方式:post结果=3
         */
        /*
            还有一个情况说明一下,当controller中存在两个完全一样的访问路径(提交方式也一样),会报一个错
            错误中有一个关键字:Ambiguous mapping,也就是模棱两可的,客户端也不知道访问哪个
         */
    }
    

5、转发和重定向

package com.ryan.RestFulController;

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

@Controller
public class ControllerTest01 {
    @RequestMapping("/t1")
    public String test01(Model model){
        model.addAttribute("msg", "springmvc");
        //有视图解析器的情况下,return "test"默认就是转发
        //return "test";
        //如果想要重定向的话,需要在前面加一个redirect:的前缀
        return "redirect:/index.jsp";
    }
    //上面的是在有视图解析器的情况下,如果没有视图解析器的话会怎么样呢?
    @RequestMapping("/t2")
    public String test02(Model model){
        model.addAttribute("msg", "你好");
        //如果没有视图解析器,转发也要加上前缀才行
        return "forward:/WEB-INF/jsp/test.jsp";
    }

    //总结:即使没有视图解析器,我们也可以完成转发和重定向的功能
    //但是在实际开发中,没什么事不会这么做的,一般都是有视图解析器的
}

6、springmvc处理数据

处理提交数据,分为三种情况

  1. 提交的域名称和处理方法的参数名一致
    • 可以直接接受
  2. 提交的域名称和处理方法的参数名不一致
    • 需要在参数前添加注解
  3. 提交的数据是一个对象
    • 自定义一个对象,属性和提交的数据名一样即可
package com.ryan.RestFulController;

import com.ryan.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;

@Controller
public class DataController {

    //用户提交数据名称为name
    //当提交数据名称和处理方法参数名称一致
    @GetMapping("/t1")
    public String test1(String name, Model model){
        model.addAttribute("msg", name);
        return "test";
    }
    //如果不一致,需要添加注解使其一致
    @GetMapping("/t2")
    public String test2(@RequestParam("name") String username, Model model){
        model.addAttribute("msg", "kobe");
        return "test";
    }

    //如果前端传的是一个User对象:id=1&name=ryan&age=18
    //自定一个类,并作为处理方法的参数
    @GetMapping("/t3")
    public String test3(User user, Model model){
        model.addAttribute("msg", user.toString());
        return "test";
    }

    /*
        注意:
            前两种情况,无论名称是否一直,都建议把@RequestParam注解加上,知道是要从前端接收数据的
            第三种情况,对象的属性名称要保持一致, 如果不一致的话,对应的属性就是null
     */
}

补充:除了用Model之外,我们还可以使用ModelMap,但在使用上,本质上一样的

对比:

Model:只有寥寥几个方法,适合存储数据,简化了新手对Model对象的操作和理解
ModelMap:继承了LinkedMap,除了实现自身的一些方法,同样继承了LinkedMap的方法和特性
ModelAndView:可以在存储数据的同时,进行设置返回的逻辑和视图,进行控制展示层的跳转

当然以后开发考虑更多的是性能和优化,就不能单单仅限于此的了解

建议:请使用80%的时间打好扎实的基础,剩下18%的时间研究框架,2%的时间去学习英语,框架的官方文档永远是最好的教程。

7、乱码问题

在前端提交中文数据的时候,可能会产生乱码的问题,这时候我们该怎么解决呢?

springmvc提供了一个一套解决方案,在web.xml中配置好过滤器就行:

<!--解决中文乱码问题-->
<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>
<!--注意这里要写/*,不然会过掉jsp页面-->
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

8、json使用

现在都流行前后端分离,有时候前端返回一些json对象给我们,我们要会解析,同样的,我们最后也需要将数据转化为json格式返回给前端,这就要求我们要使用相关工具类了,主要有两个:

方式一:jackson

jackson是目前比较好的json解析器了,当然工具不止这个,比如还有阿里巴巴的fastjson,等会再讲

使用:

  1. 确保导入依赖包和lib

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.10.2</version>
    </dependency>
    
  2. 编写配置文件,并解决乱码 问题

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <context:component-scan base-package="com.ryan.controller"/>
    
        <!--当我们在实体类都用注解的话,下面这两个也可以省去了-->
        <!--<mvc:default-servlet-handler/>
        <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>
    
        <!--解决json数据中文乱码问题-->
        <mvc:annotation-driven>
            <mvc:message-converters register-defaults="true">
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/html;charset=UTF-8</value>
                            <value>application/json;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
    
    </beans>
    
  3. 编写实体类测试

    package com.ryan.controller;
    
    import com.alibaba.fastjson.JSON;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.ryan.pojo.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Controller
    public class JsonController {
        //如果添加一个@ResponseBody注解,返回结果就不会走解析器了,直接返回字符串
        @RequestMapping("/j1")
        @ResponseBody
        public String test() throws JsonProcessingException {
            ObjectMapper mapper = new ObjectMapper();
            User user = new User(1, "甘志鹏", 20);
            String str = mapper.writeValueAsString(user);
            return str;//{"id":1,"name":"???","age":20}
            //springmvc可以帮我们解决乱码问题,在spring中配置就好
        }
    
        //java对象转换为json数据
        @RequestMapping("/j2")
        @ResponseBody
        public String tes2() throws JsonProcessingException {
            ObjectMapper mapper = new ObjectMapper();
            List<User> users = new ArrayList<>();
            User user1 = new User(1, "甘志鹏1号", 20);
            User user2 = new User(2, "甘志鹏2号", 20);
            User user3 = new User(3, "甘志鹏3号", 20);
            User user4 = new User(4, "甘志鹏4号", 20);
            users.add(user1);
            users.add(user2);
            users.add(user3);
            users.add(user4);
            String str = mapper.writeValueAsString(users);
            return str;
            /*
            [{"id":1,"name":"甘志鹏1号","age":20},
            {"id":2,"name":"甘志鹏2号","age":20},
            {"id":3,"name":"甘志鹏3号","age":20},
            {"id":4,"name":"甘志鹏4号","age":20}]
            */
        }
    }
    

方式二:FastJson(阿里巴巴的)

  1. 导入依赖

    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.68</version>
    </dependency>
    
  2. 编写实体类测试

    package com.ryan.controller;
    
    import com.alibaba.fastjson.JSON;
    import com.ryan.pojo.User;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import java.util.ArrayList;
    import java.util.List;
    
    @Controller
    public class FastJson {
        @ResponseBody
        @RequestMapping("/f1")
        public String test1(){
            List<User> users = new ArrayList<>();
            User user1 = new User(1, "甘志鹏1号", 20);
            User user2 = new User(2, "甘志鹏2号", 20);
            User user3 = new User(3, "甘志鹏3号", 20);
            User user4 = new User(4, "甘志鹏4号", 20);
            users.add(user1);
            users.add(user2);
            users.add(user3);
            users.add(user4);
            String str = JSON.toJSONString(users);
            return str;
            /*
            [{"age":20,"id":1,"name":"甘志鹏1号"},
            {"age":20,"id":2,"name":"甘志鹏2号"},
            {"age":20,"id":3,"name":"甘志鹏3号"},
            {"age":20,"id":4,"name":"甘志鹏4号"}]
             */
    
        }
    }
    

9、ajax

10、拦截器

10.1、概述:

  • SpringMVC的处理器拦截器类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理,开发者可以自己定义一些拦截器来实现特定的功能
  • 过滤器与拦截器的区别:拦截器是AOP思想的具体应用

过滤器:

  • servlet规范中的一部分,任何javaweb工程都可以使用
  • 在url-pattern中配置了/*之后,可以对所有要访问的资源进行拦截

拦截器:

  • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
  • 拦截器只会拦截访问的控制器方法,如果访问的是jsp/html/css/image/js是不会进行拦截的

10.2、自定义拦截器

那如何实现拦截器呢?

想要自定义拦截器,必须实现HandlerInterceptor接口

  1. 新建一个Module,添加web支持

  2. 配置web.xml和springmvc-servlet.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:springmvc-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>
    
        <!--解决中文乱码问题-->
        <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>
    
    </web-app>
    
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <context:component-scan base-package="com.ryan.controller"/>
    
        <mvc:default-servlet-handler/>
        <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>
    
        <!--解决json数据中文乱码问题-->
        <mvc:annotation-driven>
            <mvc:message-converters register-defaults="true">
                <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                    <property name="supportedMediaTypes">
                        <list>
                            <value>text/html;charset=UTF-8</value>
                            <value>application/json;charset=UTF-8</value>
                        </list>
                    </property>
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>
    
        <!--拦截器-->
        <mvc:interceptors>
            <mvc:interceptor>
                <!--拦截哪些请求,/**表示拦截所有请求,我们这里拦截首页的访问请求-->
                <mvc:mapping path="/home"/>
                <!--拦截器在哪-->
                <bean class="com.ryan.interceptor.MyInterceptor"/>
            </mvc:interceptor>
        </mvc:interceptors>
    
    </beans>
    
  3. 编写一个拦截器

    package com.ryan.interceptor;
    
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    //实现HandlerInterceptor接口
    public class MyInterceptor implements HandlerInterceptor {
        //手动重写方法,然后需要到springmvc配置文件中配置拦截信息
        //一般只需要preHandle方法就行
        //从以下三个方法中可以看到和aop非常相似,其实这就是aop思想的一个应用,在访问某个路径时,可以在preHandle方法上增添附属功能
        //可使用request实现转发或者重定向等等
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            /*System.out.println("=========处理前==========");
            //返回false表示拦截,返回true表示放行
            return false;*/
            //那么利用这个拦截器我们做一个真实的案例,譬如没有登陆前不能访问首页,即没登陆的话需要拦截并跳转到登陆页面
            //客户端访问home==>判断是否已经登陆==>,如已登录==>放行,如未登陆==>转发至登陆页面
            HttpSession session = request.getSession();
            String user = (String) session.getAttribute("user");
            if (user != null){
                return true;
            }
            request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
            return false;
        }
    
        //后面的两个方法一般没多大用处,需要的话可以作为日志使用
        /*@Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
            System.out.println("=========处理后==========");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
            System.out.println("=========清理==========");
        }*/
    }
    
    
    package com.ryan.controller;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    
    @Controller
    public class Test {
    
        @RequestMapping("/home")
        public String home(){
            return "home";
        }
    
        @RequestMapping("/toLogin")
        public String toLogin(){
            return "login";
        }
    
        @RequestMapping("/login")
        public String login(HttpServletRequest request, String username, String password){
            //通常我们会使用session来判断用户是否已经登陆,所以登陆时应该存一个session
            HttpSession session = request.getSession();
            //当然这里规范的应该要新建一个user类的,这里只是为了测试就不建了
            session.setAttribute("user",username);
            return "redirect:/home";
        }
    
    }
    
  4. 测试

学习来源:B站up主:狂神说,有兴趣的同学可以关注学习一波,感觉还不错

期末大作业基于python的足球运动员数据分析源码+数据集(高分项目),个人经导师指导并认可通过的高分设计项目,评审分98分,项目中的源码都是经过本地编译过可运行的,都经过严格调试,确保可以运行!主要针对计算机相关专业的正在做大作业、毕业设计的学生和需要项目实战练习的学习者,资源项目的难度比较适中,内容都是经过助教老师审定过的能够满足学习、使用需求,如果有需要的话可以放心下载使用。 期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于python的足球运动员数据分析源码+数据集(高分项目)期末大作业基于pyth
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值