【SpringMVC】SpringMVC基础

目录

1、MVC简介

1.1、JSP+JavaBean模式

1.2、Servlet+JSP+JavaBean模式

1.3、MVC优缺点

2、SpringMVC

2.1、什么是SpringMVC:

2.2、优点:

3、第一个SpringMVC程序

3.1、项目结构

3.2、搭建环境

3.3、SpringMVC配置

3.4、底层原理分析

4、使用注解开发SpringMVC

4.1、项目结构:

4.2、项目步骤

5、@RequestMapping详解

5.1、解析源码

5.2、简单实例

5.3、method 属性

5.3、使用RestFul风格

6、乱码处理

7、JSON

7.1、什么是JSON

7.2、JSON语法规则

7.3、JSON与JS关系

8、Jackson

8.1、实例

8.2、自定义ObjectMapper获取工具包

8.3、项目结构


1、MVC简介

MVC 设计模式一般指 MVC 框架,M(Model)指数据模型层,V(View)指视图层,C(Controller)指控制层。使用 MVC 的目的是将 M 和 V 的实现代码分离,使同一个程序可以有不同的表现形式。其中,View 的定义比较清晰,就是用户界面。

官方配置文件:Web on Servlet Stack

  • View(视图):jsp

    • 负责格式化数据并把它们呈现给用户,包括数据展示、用户交互、数据验证、界面设计等功能。

  • Controller(控制器):servlet

    • 负责接收并转发请求,对请求进行处理后,指定视图并将结果发送给客户端。

  • Model(模型):dao,service,JavaBean

    • 模型对象拥有最多的处理任务,是应用程序的主体部分,负责数据逻辑(业务规则)的处理和实现数据操作即在数据库中存取数据。

SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式

1.1、JSP+JavaBean模式

  • y优点:适合开发业务逻辑不太复杂的web应用程序,这种模式下,JavaBean用于封装业务数据,JSP即负责处理用户请求,又显示数据。

  • 缺点:JSP+JavaBean 模式中 JSP 身兼数职,既要负责视图层的数据显示,又要负责业务流程的控制,结构较为混乱,并且也不是我们所希望的松耦合架构模式,所以当业务流程复杂的时候并不推荐使用。

1.2、Servlet+JSP+JavaBean模式

  • Servlet+JSP+JavaBean 中 Servlet 用于处理用户请求,JSP 用于数据显示,JavaBean 用于数据封装,适合复杂的 Web 程序。

  • 相比 JSP+JavaBean 模式来说,Servlet+JSP+JavaBean 模式将控制层单独划分出来负责业务流程的控制,接收请求,创建所需的 JavaBean 实例,并将处理后的数据返回视图层(JSP)进行界面数据展示。

  • Servlet+JSP+JavaBean 模式的结构清晰,是一个松耦合架构模式,一般情况下,建议使用该模式。

1.用户发送请求

2.Servlet接收请求,并调用对应的业务逻辑方法处理

3.业务处理完后,返回更新后的数据给servlet

4.servlet转向给jsp,由jsp渲染页面

5.响应给用户更新后的页面

1.3、MVC优缺点

优点:

  • 多视图共享一个模型,大大提高了代码的可重用性

  • MVC 三个模块相互独立,松耦合架构

  • 控制器提高了应用程序的灵活性和可配置性

  • 有利于软件工程化管理

总的来说,可以通过 MVC 设计模式打造出一个松耦合+高可重用性+高可适用性的完美架构。

缺点:

  • 原理复杂

  • 增加了系统结构和实现的复杂性

  • 视图对模型数据的低效率访问

MVC 并不适合小型甚至中型规模的项目,花费大量时间将 MVC 应用到规模并不是很大的应用程序,通常得不偿失,所以对于 MVC 设计模式的使用要根据具体的应用场景来决定。

2、SpringMVC

2.1、什么是SpringMVC:

  • Spring MVC 是 Spring 提供的一个基于 MVC 设计模式的轻量级 Web 开发框架,本质上相当于 Servlet。

  • SpringMVC是由Servlet+JSP+JavaBean实现的。

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

  • 它是一个典型的教科书式的mvc构架,而不像struts等都是变种或者不是完全基于mvc系统的框架,对于初学者或者想了解mvc的人来说我觉得 spring是最好的,它的实现就是教科书!第二它和tapestry一样是一个纯正的servlet系统,这也是它和tapestry相比 struts所具有的优势。而且框架本身有代码,看起来容易理解。

  • 在 Spring MVC 框架中,Controller 替换 Servlet 来担负控制器的职责,用于接收请求,调用相应的 Model 进行处理,处理器完成业务处理后返回处理结果。Controller 调用相应的 View 并对处理结果进行视图渲染,最终客户端得到响应信息。

2.2、优点:

  • 易于同其它View框架(Tiles等)无缝集成,采用IOC便于测试。

  • 清晰地角色划分,Spring MVC 在 Model、View 和 Controller 方面提供了一个非常清晰的角色划分,这 3 个方面真正是各司其职,各负其责。

  • 灵活的配置功能,可以把类当作 Bean 通过 XML 进行配置。

  • 提供了大量的控制器接口和实现类,开发者可以使用 Spring 提供的控制器实现类,也可以自己实现控制器接口。

  • 面向接口编程

  • Spring MVC 框架采用松耦合可插拔的组件结构,具有高度可配置性,比起其它 MVC 框架更具有扩展性和灵活性。

  • 真正做到与 View 层的实现无关。它不会强制开发者使用 JSP,可以根据项目需求使用 Velocity、FreeMarker 等技术。

3、第一个SpringMVC程序

3.1、项目结构

3.2、搭建环境

1.创建父工程SpringMVC并删除src文件

2.建立一个SpringMVC-01子项目,添加Web app支持

右键子项目-->Add Frameworks Support-->Web Application-->ok创建成功

3.导入SpringMVC的jar依赖

Spring MVC 依赖 JAR 文件包括 Spring 的核心 JAR 包和 commons-logging 的 JAR 包。

 
 
<dependencies>
    <!--J2EE-->
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet.jsp</groupId>
        <artifactId>jsp-api</artifactId>
        <version>2.2</version>
    </dependency>
​
    <!--springframework-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.2.3.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>com.github.stefanbirkner</groupId>
        <artifactId>system-rules</artifactId>
        <version>1.16.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.8.9</version>
    </dependency>
</dependencies>

3.3、SpringMVC配置

Spring MVC 是基于 Servlet 的,DispatcherServlet 是整个 Spring MVC 框架的核心,主要负责截获请求并将其分派给相应的处理器处理。所以配置 Spring MVC,首先要定义 DispatcherServlet。跟所有 Servlet 一样,用户必须在 web.xml 中进行配置。

1.注册DispatcherServlet

在web.xml中部署DispatcherServlet:

<display-name>springMVC</display-name>
<!-- 1.注册DispatcherServlet -->
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--关联一个springmvc的配置文件:【servletname】-servlet.xml-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc-servlet.xml</param-value>
    </init-param>
    <!-- 表示容器再启动时立即加载servlet -->
    <!--启动级别1-->
    <load-on-startup>1</load-on-startup>
</servlet>
<!-- / 匹配所有请求,不包括.jsp-->
<!-- /* 匹配所有请求,包括.jsp-->
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <!-- 处理所有URL -->
    <url-pattern>/</url-pattern>
</servlet-mapping>

2.创建Spring MVC配置文件(springmvc-servlet.xml)

文件名格式:【servletname】-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">
​
</beans>

3.配置文件中添加处理映射器

<!--处理映射器-->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

4.配置文件中添加处理器适配器

<!--处理器适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>  <!--尝试把它注释掉在运行程序看看->可以运行-->

5.配置文件中添加视图解析器

<!--视图解析器:DispatcherServlet给他的ModelAndView-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
    <!--前缀-->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!--前缀-->
    <property name="suffix" value=".jsp"/>
</bean>

6.编写要操作的业务Controller

有两种方法:1.实现Controller接口;2.增加注解

需要返回一个ModelAndview,封装数据和要跳转的视图

public class FirstController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //ModelAndView 模型和视图
        ModelAndView mv = new ModelAndView();
​
        //封装对象,放在ModelAndView中
        mv.addObject("msg","Hello SpringMVC");
        //封装要跳转的视图,放在ModelAndView中
        mv.setViewName("hello");
        return mv;
    }
}

7.创建视图

在WEB-INF下添加一个hello.jsp

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

8.在springmvc-servlet.xml容器中注册bean

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

然后就可以运行程序了。

注意:如果遇到404的错误

代码没错的前提下,可能是:

1.查看控制台输出,看是不是却是jar包

2.jar包存在,显示无法输出,则在idea项目发布中,添加lib依赖

然后选择里面所有的包,导进去。

3.重启Tomcat

3.4、底层原理分析

宏观视图:

微观视图:

流程解析:

1.DispatcherServlet是前置控制器,是整个SpringMVC的控制中心。用户发送请求,DispatcherServlet接收并拦截请求

  1. 假设请求的URL为:http://localhost:8080/SpringMVC_01_war_exploded/hello

  2. url将会被分为三部分

    1. http://localhost:8080 服务器域名

    2. /SpringMVC_01_war_exploded 部署在服务器上的站点

    3. /hello 控制器

    4. 请求位于服务器http://localhost:8080上的/站点的hello控制器

2.HandlerMapping为处理器映射。DispatcherServlet调用HandlerMapping,HandlerMapping根据请求url查找Handler。

3.HandlerExecution表示具体的Handler,其主要作用是根据url查找控制器,如上url被查找控制器为:hello。

4.HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。

5.HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler。

6.Handler让具体的Controller执行。

7.Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。

8.HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。

9.DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的逻辑视图名。

10.视图解析器将解析的逻辑视图名传给DispatcherServlet。

11.DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。

12.最终视图呈现给用户。

本解析参考自:狂神说SpringMVC笔记_liufengxian3399的博客-CSDN博客

4、使用注解开发SpringMVC

4.1、项目结构:

4.2、项目步骤

  1. 创建子项目SpringMVC-02-annotation

  2. 添加SpringMvc需要的依赖(前面有)

主要有:Spring框架核心库、SpringMVC、servlet、JSTL等

  1. 配置web.xml

    1. web.xml需要最新版的 4.0

    2. 注册DispatcherServlet

    3. 关联SpringMVC的配置文件---->【servletname】-servlet.xml

    4. 启动级别为1

    5. 映射路径为/ 【注意:不要用/*,会遇到404报错】

      <?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">
          <display-name>springMVC</display-name
              <!-- 1.注册DispatcherServlet -->
              <servlet>
                  <servlet-name>springmvc</servlet-name>
                  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
                  <!--关联一个springmvc的配置文件:【servletname】-servlet.xml-->
                  <init-param>
                      <param-name>contextConfigLocation</param-name>
                      <param-value>classpath:springmvc-servlet.xml</param-value>
                  </init-param>
                  <!-- 表示容器再启动时立即加载servlet -->
                  <!--启动级别1-->
                  <load-on-startup>1</load-on-startup>
              </servlet>
              <!-- / 匹配所有请求,不包括.jsp-->
              <!-- /* 匹配所有请求,包括.jsp-->
              <servlet-mapping>
                  <servlet-name>springmvc</servlet-name>
                  <!-- 处理所有URL -->
                  <url-pattern>/</url-pattern>
              </servlet-mapping>
      ​
              </web-app>
      1. 添加SpringMVC配置文件(springmvc-servlet.xml)

        1. 使用context:component-scan:扫描指定包文件,让指定包下的注解生效

        2. default-servlet-handler:静态资源过滤

        3. annotation-driven:MVC注解驱动,相当于HandlerMapping和HandlerAdapter

        4. 配置视图解析器

      <?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 https://www.springframework.org/schema/mvc/spring-mvc.xsd">
      ​
          <!--自动扫描包,让指定包下的注解生效,由IOC容器同意管理-->
          <context:component-scan base-package="com.wen.controller"/>
          <!--不处理静态资源-->
          <mvc:default-servlet-handler/>
          <mvc:annotation-driven/>
      ​
          <!--视图解析器:DispatcherServlet给他的ModelAndView-->
          <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-INF、目录下,这样是private的,客户端是访问不到的,如果是直接存放在WEN-INF中的话,是公共的,客户端是可以访问到的。

      1. 创建controller

      编写java控制类:通过上面的base-package="com.wen.controller"可以看出,我的controller类是在=在com.wen.controller下的

      @Controller
      public class SecondController {
          //访问地址:http://localhost:8080/项目名/hello
          @RequestMapping("/hello")
          public String hello(Model model){
              //向模型中添加属性msg与其值,返回到jsp中
              model.addAttribute("msg","Hello Second SpringMVC");
              //返回给视图解析器一个字符串hello,然后通过前缀和后缀的拼接,成为:/WEB-INF/jsp/hello.jsp
              return "hello";
          }
      }
      • Controller注解

        • @Controller注解用于声明某类的实例是一个控制器,能够让SpringIOC容器初始化时自动扫描到

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

      • RequestMapping注解

        • 一个控制器内有多个处理请求方法,如增、删、改、查等,每个方法都负责不同的请求操作,@RequestMapping就是负责将请求映射到对应的控制器方法上。

        • 在基于注解的控制器类中可以为每个请求编写对应的处理方法。使用 @RequestMapping 注解将请求与处理方法一 一对应即可。

        • @RequestMapping注解可用在类或方法上

          • 用在类上:

          @Controller
          @RequestMapping("SecondController")
          public class SecondController {
              @RequestMapping("/hello")
              public String hello(Model model){
                  model.addAttribute("msg","Hello Second SpringMVC");
                  return "hello";
              }
          }

          他的请求路径为:http://localhost:8080/02/SecondController/hello

          • 用在方法上:

          @Controller
          public class SecondController {
              @RequestMapping("/hello")
              public String hello(Model model){
                  model.addAttribute("msg","Hello Second SpringMVC");
                  return "hello";
              }
          }

          他的请求路径为:http://localhost:8080/02/hello

          1. 创建视图层

          前面讲过,视图层是建在WEB-INF下的 ,在WEB-INF下建一个jsp包,里面建一个hello.jsp文件。

          注意:视图是可以直接从Controller里提取数据,通过EL表示(${})去除model中存放的值或对象。

          <%@ page contentType="text/html;charset=UTF-8" language="java" %>
              <html>
                  <head>
                      <title>Title</title>
                  </head>
                  <body>
                      ${msg}
                  </body>
              </html>
          1. 配置tomcat运行即可

          注意事项:可能会遇到404,前面讲过第一个SpringMVC中讲过,要先去看这个项目里有没有lib文件,没有的话创建一个然后把jar包全导进去。

5、@RequestMapping详解

在Spring MVC 中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置

RequestMapping可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

5.1、解析源码

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";
​
    @AliasFor("path")
    String[] value() default {};
​
    @AliasFor("value")
    String[] path() default {};
​
    RequestMethod[] method() default {};
​
    String[] params() default {};
​
    String[] headers() default {};
​
    String[] consumes() default {};
​
    String[] produces() default {};
}
  1. @Target({ElementType.TYPE, ElementType.METHOD})

@Target有两个属性,分别为ElementType.TYPE和ElementType.METHOD,意思是可以在方法的声明中使用。

  1. String name() default ""

指定请求路径的地址

  1. @AliasFor("path")、@AliasFor("value")

指定请求路径的地址,其中path和value互为别名,@AliasFor是为了让被注解的能互相使用

  1. RequestMethod[] method() default {}

指定请求方式,是一个RequestMethod数组,可以配置多个方法

  1. String[] params() default {}

指定参数类型

  1. String[] headers() default {}

指定请求的请求头

  1. String[] consumes() default {}

指定数据请求的格式

  1. String[] produces() default {}

指定返回的内容类型

5.2、简单实例

1、此实验的环境为使用注解开发的环境(主要是懒)SpringMVC-02-annotation

2、创建RequestMappingTest1类

@Controller
public class RequestMappingTest1 {
    //@RequestMapping 中的 value 和 path 属性(这两个属性作用相同,可以互换,如果仅有这一个属性,则可以省略,下面两个例子均采用省略的方式)
    @RequestMapping(value = "/add")
    public String test1(int a, int b, Model model){
        int x = a+b;
        model.addAttribute("msg","结果为:" + x);
        return "test1";
    }
}

3、创建对应的test1.jsp

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

4、运行程序,输入对应值

http://localhost:8080/02/add?a=3&b=6

这个是默认的输入方式

5.3、method 属性

@RequestMapping 中的 method 主要用来定义接收浏览器发来的何种请求。在Spring中,使用枚举类

public enum RequestMethod {
    GET,
    HEAD,
    POST,
    PUT,
    PATCH,
    DELETE,
    OPTIONS,
    TRACE;
​
    private RequestMethod() {
    }
}

通过method=RequestMethod.GET指定test1()方法仅使用GET方式发送请求

@Controller
public class RequestMappingTest1 {
    //@RequestMapping 中的 value 和 path 属性(这两个属性作用相同,可以互换,如果仅有这一个属性,则可以省略,下面两个例子均采用省略的方式)
    @RequestMapping(value = "/add",method = RequestMethod.GET)
    public String test1(int a, int b, Model model){
        int x = a+b;
        model.addAttribute("msg","结果为:" + x);
        return "test1";
    }
}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>Title</title>
    </head>
    <body>
        <form action="add" method="post">
            <input type="text" name="a">
            <input type="text" name="b">
            <input type="submit">
        </form>
    </body>
</html>

可以看到,put.jsp上传的为post方法,而接受的却是get方法,会导致无法匹配

其他方法同理。

所有地址栏请求默认都会是HTTP GET类型的

方法级别的注解变体有:

@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping

他们都是一个组合注解,比如:

@GetMapping就相当于@RequestMapping(method = RequestMethod.GET)的一个快捷方式。极为便利!

5.3、使用RestFul风格

在URL中,会有一些不同的写法风格

传统方式操作资源

/*
http://127.0.0.1/item/queryUser.action?id=1   查询,GET 
http://127.0.0.1/item/saveUser.action             新增,POST 
http://127.0.0.1/item/updateUser.action          更新,POST 
http://127.0.0.1/item/deleteUser.action?id=1  删除,GET或POST
*/

使用RestFul操作资源

/*
【GET】 /users # 查询用户信息列表
​
【GET】 /users/01 # 查看某个用户信息
​
【POST】 /users # 新建用户信息
​
【PUT】 /users/01 # 更新用户信息(全部字段)
​
【PATCH】 /users/01 # 更新用户信息(部分字段)
​
【DELETE】 /users/01 # 删除用户信息
*/

案例:

@Controller
public class RequestMappingTest1 {
    //@RequestMapping 中的 value 和 path 属性(这两个属性作用相同,可以互换,如果仅有这一个属性,则可以省略,下面两个例子均采用省略的方式)
    @GetMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a, @PathVariable int b, Model model){
        int x = a+b;
        model.addAttribute("msg","结果为:" + x);
        return "test1";
    }
}

6、乱码处理

在传输数据时会有中文乱码现象,解决办法:

  1. 自定义过滤器

  2. 使用SpringMVC自带的过滤器

自定义过滤器这里就不说了,这里主要讲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>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

注意,<url-pattern>这里要写/*不然无法访问jsp文件!

7、JSON

7.1、什么是JSON

  • JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。

  • 它基于 ECMAScript(欧洲计算机协会制定的js规范)的一个子集,采用完全独立于编程语言的文本格式来存储和表示数据。

  • 简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。

  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。

7.2、JSON语法规则

任何JavaScript支持的类型都可以通过JSON来表示,例如字符串、数字、对象、数组等。

  • 方括号保存的是数组

  • 花括号保存的是对象

  • 对象则由键值对来表示,数据之间用逗号分隔

7.3、JSON与JS关系

很多人搞不清楚 JSON 和 JS 对象的关系,甚至连谁是谁都不清楚。其实,可以这么理解:

  • JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。

//编写一个JavaScript对象
var user = {
    name : "张三",
    age : 21,
    sex : "男"
};
console.log(user);

  • 通过stringify将js对象转换为json对象

//将js对象转换为json对象
var json = JSON.stringify(user);
console.log(json);

可以看出js声明的是一个对象,通过stringify转换为json后就变为了一个字符串。

  • 通过parse将json对象转换为JavaScript对象

//将json对象转换为JavaScript对象
var js = JSON.parse(json);
console.log(js);

8、Jackson

我们需要通让ava将数据通过json输出到前端,可以通过Jackson来实现这个操作。

优点:

  1. Jackson 是当前用的比较广泛的,用来序列化和反序列化 json 的 Java 的开源框架

  2. Jackson 所依赖的 jar 包较少 ,简单易用

  3. 与其他 Java 的 json 的框架 Gson 等相比, Jackson 解析大的 json 文件速度比较快

  4. Jackson 运行时占用内存比较低,性能比较好

  5. Jackson 有灵活的 API,可以很容易进行扩展和定制。

Jackson的核心模块由三部分组成

  • 核心包:jackson-core,提供基于"流模式"解析的相关 API,它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json

  • 注解包:jackson-annotations,提供标准注解功能

  • 数据绑定包:jackson-databind , 提供基于"对象绑定" 解析的相关 API ( ObjectMapper ) 和"树模型" 解析的相关 API (JsonNode);基于"对象绑定" 解析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API

8.1、实例

1、在pom.xml中导入Jackson的依赖

<dependency>
    <groupId>com.mastfrog</groupId>
    <artifactId>jackson</artifactId>
    <version>2.7.3</version>
</dependency>

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">
    <display-name>springMVC</display-name>
​
​
​
    <!-- 1.注册DispatcherServlet -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件:【servletname】-servlet.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!-- 表示容器再启动时立即加载servlet -->
        <!--启动级别1-->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <!-- / 匹配所有请求,不包括.jsp-->
    <!-- /* 匹配所有请求,包括.jsp-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <!-- 处理所有URL -->
        <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>

3、在resources下配置springmvc-servlet.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           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 https://www.springframework.org/schema/mvc/spring-mvc.xsd">
​
    <!--自动扫描包,让指定包下的注解生效,由IOC容器同意管理-->
    <context:component-scan base-package="com.wen.controller"/>
​
    <!--视图解析器:DispatcherServlet给他的ModelAndView-->
    <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、编写实体类User,目的:将User里面的信息输出给前端页面

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private String name;
    private int age;
    private String sex;
​
}

5、创建UserController类实现方法

@Controller
public class UserController {
    @RequestMapping("/json1")
    @ResponseBody   //通过这个注解,不会走视图解析器,会直接返回一个字符串,也可以直接在类上使用@RestController,替换掉@Controller和@ResponseBody ,表明这个类下的所有方法都不走视图解析器
    public String json1() throws JsonProcessingException {
        //Jackson
        ObjectMapper mapper = new ObjectMapper();
​
        //创建一个对象
        User user = new User("张三", 21, "男");
​
        String str = mapper.writeValueAsString(user);
        return str;
    }
}

返回结果:

{"name":"??","age":21,"sex":"?"}

6、解决乱码问题

  • 手动解决

    • @RequestMapping(value = "/json1",params = "application/json;charset=utf-8")

  • SpringMVC配置统一指定:在SpringMVC的配置文件上添加一段消息StringHttpMessageConverter转换配置

    • <!--乱码问题配置-->
      <mvc:annotation-driven>
          <mvc:message-converters>
              <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>

8.2、自定义ObjectMapper获取工具包

如果每次传输数据都要去new一个ObjectMapper会很麻烦,所有创建一个工具包,自动new

1、创建一个工具包类

public class JsonUtil {
    //实现代码的复用
    public static String getJson(Object obj) {
        return getJson(obj,"yyy-MM-dd HH:mm:ss");   //自己标准化的时间格式
    }
​
    public static String getJson(Object obj,String dateFormat){
        ObjectMapper mapper = new ObjectMapper();
​
        //不使用时间戳方式
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);
        //自定义时间格式
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);    //自定义时间格式
        mapper.setDateFormat(sdf);
        try {
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

2、调用工具包里的方法获取时间

@RequestMapping(value = "/json3")
//@ResponseBody   //通过这个注解,不会走视图解析器,会直接返回一个字符串
public String json3() throws JsonProcessingException {
    Date date = new Date();
​
    return JsonUtil.getJson(date);
}

结果

"2021-12-02 01:15:51"

3、调用工具包里的方法,输出一个list

@RequestMapping(value = "/json2")
//@ResponseBody   //通过这个注解,不会走视图解析器,会直接返回一个字符串
public String json2() throws JsonProcessingException {
​
    //创建一个对象
    List<User> userList = new ArrayList<User>();
    User user1 = new User("老1", 21, "男");
    User user2 = new User("老2", 21, "男");
    User user3 = new User("老3", 21, "男");
​
    userList.add(user1);
    userList.add(user2);
    userList.add(user3);
​
    return JsonUtil.getJson(userList);
}

结果

[{"name":"老1","age":21,"sex":"男"},{"name":"老2","age":21,"sex":"男"},{"name":"老3","age":21,"sex":"男"}]

8.3、项目结构

猜你喜欢

转载自blog.csdn.net/m0_46313726/article/details/121668540