0
点赞
收藏
分享

微信扫一扫

SpringMVC详解

boom莎卡拉卡 2022-05-05 阅读 45

SpringMVC详解

  1. SpringMVC:SpringMVC的执行流程
  2. SpringMVC:SSM框架整合

1、回顾MVC

  1. MVC: 模型(dao,service) 视图(jsp) 控制器(servlet),是一种软件设计规范
  2. 是将业务逻辑、数据1、显示分离的方法来组织代码
  3. MVC主要作用是降低了视图与业务逻辑间的双向耦合
  4. MVC是一种架构模式。
  • 假设:问你的项目的架构,是设计好的,还是演进的?

演进的。没有一个项目的架构是一步就能设计好的,都是慢慢演化、进化来的

  1. 准备工作
  • 创建maven项目,父项目、子项目
  • 父项目中导入公共依赖
  <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.9.RELEASE</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>
  • 创建servlet
  • 创建jsp
  1. MVC框架要做哪些事情
  • 将url映射到java类或java类的方法
  • 封装用户提交的数据
  • 处理请求–调用相关的业务处理–封装相应数据
  • 将响应的数据进行渲染,jsp/html等表示层数据

2、初识SpringMVC

2.1、SpringMVC是什么

  1. SpringMVC是Spring Framework的一部分,是基于java实现MVC的轻量级web框架
  2. SpringMvc框架像许多其他MVC框架一样,以请求为驱动,围绕一个中心servlet分派请求及提供其他功能。DispatcherServlet是一个实际的servlet(它继承自HttpServlet基类)

2.2、为什么要学习SpringMVC

  1. SpringMVC的特点:
  • 轻量级,简单易学
  • 高效,基于请求响应的MVC框架
  • 与Spring兼容性好,无缝结合 (我们可以将SpringMVC需要的所有的bean注册到spring中)
  • 约定优于配置
  • 功能强大:RESTful、数据验证、格式化、本地化、主题等
  • 简洁灵活
  • 用的人多,使用的公司也多。

2.3、SpringMVC原理

  1. 当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型相应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。

  2. Spring的web框架围绕DispatcherServlet设计,DispatcherServlet的作用是将请求分发到不同的处理器。

  3. 用户发送请求---->前端控制器(委托请求给处理器)---->页面控制器/处理器(调用业务对象)—>模型(返回模型数据)—>页面控制器/处理器(返回ModelAndView)—>前端控制器(产生响应)—>用户

2.4、Hello,SpringMVC

  1. 新建一个Moudle,添加web的支持
  2. 确定导入了SpringMVC的依赖
  3. 配置web.xml,注册DispatcherServlet
<?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">
<!--配置DispatchServlet:这个是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>
<!--        启动级别:1,服务器一启动它就启动-->
        <load-on-startup>1</load-on-startup>
    </servlet>
<!--
在springMVC中,/和/*区别:
/  :只匹配所有的请求,不会去匹配jsp页面

/*  :匹配所有的请求,包括jsp页面
-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>
  1. springmvc-servlet
<?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"/>
<!--    视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
<!--        前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
<!--        后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>

<!-- BeanNameUrlHandlerMapping:bean   -->
    <bean id="/hello" class="com.qian.controller.HelloController"/>
</beans>
  1. 写业务 ,helloController.java
package com.qian.controller;


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 HelloController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mv = new ModelAndView();
        //业务代码
        String result = "HelloSpringMVC";
        mv.addObject("msg",result);
        //视图跳转
        mv.setViewName("test");



        return mv;
    }
}

  • 报错404:

查看项目结构工件中,是否在项目下有lib目录,如果没有需要自己创建一个lib目录,并把所有依赖jar包添加到lib目录下。

3、使用注解开发SpringMVC

  1. 建一个新的子项目
  2. 导入静态资源过滤的相关配置
<build>
<resources>
    <resource>
        <directory>src/main/java</directory>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
    </resource>
    <resource>
        <directory>src/main/resources</directory>
        <includes>
            <include>**/*.properties</include>
            <include>**/*.xml</include>
        </includes>
        <filtering>false</filtering>
    </resource>
</resources>
</build>


  1. 导入相关依赖
  2. 配置web.xml
  • 注意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">
<!--    注册servlet-->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--        通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
        <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>
  1. 配置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.qian.controller"/>
    <!--让spring mvc不处理静态资源,.css/.js/.mp3等 过滤这些静态资源-->
    <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>

  1. helloController.java
package com.qian.controller;

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

@Controller
public class HelloController {
    @RequestMapping("/hello")
    public String hello(Model model){

        //封装数据  在模型中添加msg与值,可以在jsp页面中取出并渲染
        model.addAttribute("msg","hello,SpringMVCAnnotation!");
        return "hello";   //会被视图解析器处理

    }
}

  1. hello.jsp
<%--
  Created by IntelliJ IDEA.
  User: HUAWEI
  Date: 2022/5/4
  Time: 17:01
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
${msg}

</body>
</html>

  • 使用springMVC必须配置的三大件:

    • 处理器映射器
    • 处理器适配器
    • 视图解析器

    通常我们只需要手动配置视图解析器,而处理器映射器和处理器适配器只需要开启注解驱动即可,省去了大段的xml配置

4、Controller配置总结

  1. 控制器Controller
  • 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义(推荐)两种方式实现。
  • 控制器负责解析用户的请求并将其转换为一个模型
  • 在SpringMVC中一个控制器类可以包含多个方法

4.1、实现Controller接口

  1. 步骤:
  • 实现Controller接口 ,Controller是一个接口,在org.springframework.web.servlet.mvc包下,接口中只有一个方法
package com.qian.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

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

  • 在spring中注册bean
    <bean name="/t1" class="com.qian.controller.ControllerTest1"/>
  • 编写前端页面

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

  1. 说明:
  • 实现接口Controller定义控制器是较老的办法
  • 缺点是:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较麻烦

4.3、使用注解@Controller

  1. @Controller 注解类型用于声明Spring类的实例是一个控制器
  2. 需要在配置文件中声明组件扫描,自动扫描指定的包,下面所有的注解类交给IOC容器管理
   <context:component-scan base-package="com.qian.controller"/>
  1. 增加一个controller类,使用注解实现
package com.qian.controller;

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

@Controller
//被这个注解的类中的所有方法,如果返回值是String。并且有具体页面可以跳转,那么就会被视图解析器解析
public class ControllerTest2 {
    @RequestMapping("/t2")
    public String test2(Model model){
        model.addAttribute("msg","hello,xqh");

        return "test";  //找的是  /WEB-INF/jsp/test.jsp
    }

}


  • 说明:推荐使用注解方式来配置controller。

4.4、RequestMapping说明

  1. @RequestMapping 注解用于映射url到控制器或一个特定的处理程序方法。可用于类或方法上,用于类上,表示类中的所有相应请求的方法都是以该地址作为父路径
  • 在类和方法上同时使用RequestMapping
package com.qian.controller;

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

@Controller
@RequestMapping("/c3")
public class ControllerTest3 {

    @RequestMapping("/t1")
    public String test3(Model model){
        model.addAttribute("msg","你好");

        return "test";
    }
}

要跳转到这个页面,必须加上父项目 8080/c3/t1。 需要先指定类的路径再指定方法的路径

5、RestFul风格

  • 用/分隔开,现在大多数的网站都是用restful风格
  1. 概念:
  • RestFul就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,基于这个风格设计的软件可以更简介更有层次,更易于实现缓存等机制。
  1. 功能
  • 资源:互联网所有的事物都可以被抽象为资源

  • 资源操作:使用POST、Delete、PUT、GET,使用不同方法对资源进行操作

  • 分别对应 添加、删除、修改、查询

  • 传统方式操作资源 :通过不同的参数来实现不同的效果! 方法单一:post、get,只是改变参数来实现增删改查

  • 现在使用RestFul操作资源 :通过四种请求方式来实现不同的效果 POST、Delete、PUT、GET。请求地址一样,但是功能可以不同!

原来的风格:http://localhost:8080/add?a=1&b=2

package com.qian.controller;

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

@Controller
public class RestFulController {
    //原来的风格:http://localhost:8080/add?a=1&b=2
    @RequestMapping("/add")
    public String test1(int a, int b, Model model){
        int res = a+b;
        model.addAttribute("msg","结果为"+res);
        return "test";
    }
}

RestFul风格:http://localhost:8080/add/1/2

package com.qian.controller;

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

@Controller
public class RestFulController {
    //原来的风格:http://localhost:8080/add?a=1&b=2
    @RequestMapping("/add/{a}/{b}")
    public String test1(@PathVariable int a, @PathVariable int b, Model model){
        int res = a+b;
        model.addAttribute("msg","结果为"+res);
        return "test";
    }
}

  1. 使用method属性指定请求类型
    @RequestMapping(value = "/add/{a}/{b}",method = {RequestMethod.GET})
  1. 小结:
  • 所有的地址栏请求默认都会是HTTP GET类型的
  • 指定请求类型的时候还可以使用组合注解:
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping
  • 使用路径变量的好处:
    • 使路径变得更加简洁
    • 获得参数更加方便,框架会自动进行类型转换
    • 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法。
    • 安全

6、SpringMVC:结果跳转方式

  1. 通过ModelAndView实现跳转
  • 设置ModelAndView对象,根据view的名称,和视图解析器跳到指定的页面
  • 页面: {视图解析器前缀}+ viewName + {视图解析器后缀}
<!--    视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
package com.qian.controller;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
//只要实现了controller 接口的类,说明这就是一个控制器,可以返回一个ModelAndView
public class ControllerTest1 implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","ControllerTest1");
        mv.setViewName("test");
        return mv;
    }
}
//更多的是使用注解这种方式
@Controller
//被这个注解的类中的所有方法,如果返回值是String。并且有具体页面可以跳转,那么就会被视图解析器解析
public class ControllerTest2 {
    @RequestMapping("/t1")
    public String test2(Model model){
        model.addAttribute("msg","hello,xqh");

        return "test";  //找的是  /WEB-INF/jsp/test.jsp
    }

}
  1. 通过设置ServletAPI
  • 不需要视图解析器
    • 通过HttpServletResponse进行输出
    • 通过HttpServletResponse实现重定向
    • 通过HttpServletResponse实现转发
package com.qian.controller;

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

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@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";
    }
}

  1. SpringMVC实现跳转
  • 通过SpringMVC来实现转发和重定向----无需视图解析器

转发

package com.qian.controller;

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

@Controller
public class ModelTest2 {
    @RequestMapping("/m2/t1")
    public String test2(Model model){
        model.addAttribute("msg","hello,xqh");
        return "forward:/WEB-INF/jsp/test.jsp";//转发
    }
}

重定向

package com.qian.controller;

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

@Controller
public class ModelTest2 {
    @RequestMapping("/m2/t1")
    public String test2(){
        return "redirect:/index.jsp";//重定向
    }
}

7、SpringMVC:数据处理

7.1、处理提交数据

  1. 提交的域名称和处理方法的参数名一致

提交数据: http://localhost:8080/t4?name=xqh

处理方法:

@Controller
public class ControllerTest4 {
    @RequestMapping("/t4")
    public String test4(String name,Model model){
        model.addAttribute("msg",name);
        return "test";

    }
}
  1. 提交的域名称和处理方法的参数名不一致

提交数据:http://localhost:8080/t4?username=xqh

处理方法:

@Controller
public class ControllerTest4 {
    @RequestMapping("/t4")
    public String test4(@RequestParam("username") String name, Model model){
        model.addAttribute("msg",name);
        return "test";

    }
}

//@RequestParam("username") String name   --"username"是域名称实际输入的名称。建议需要从前端接收的参数都使用@RequestParam加上
  1. 提交的是一个对象
  • 要求提交的表单域和对象的属性名一直,参数使用对象即可

提交数据:http://localhost:8080/user/t2?id=1&name=xqh&age=18

处理方法:

  //前端接收的是一个对象: id,name,age
    @RequestMapping("/t2")
    public String test2(User user){
        System.out.println(user);
        return "test";
    }

后台输出: User(id=1, name=xqh, age=18)

7.2、数据显示到前端

  1. ModelAndView
public class ControllerTest1 implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","ControllerTest1");
        mv.setViewName("test");
        return mv;
    }
}
  1. 通过ModelMap
 @RequestMapping("/t3")
    public String test3(@RequestParam("username")String name , ModelMap map){
        //封装要显示到视图中的数据
        //相当于req.setAttribute("name",name);
        map.addAttribute("name",name);
        System.out.println(name);
        return "test";
    }
  1. 通过Model
@Controller
@RequestMapping("/c3")
public class ControllerTest3 {

    @RequestMapping("/t1")
    public String test3(Model model){
        model.addAttribute("msg","你好");

        return "test";
    }
}

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

7.3、乱码问题

  • 写一个表单
<%--
  Created by IntelliJ IDEA.
  User: HUAWEI
  Date: 2022/5/4
  Time: 20:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="/e1" method="post">
    <input type="text" name="name">
    <input type="submit">
</form>
</body>
</html>

  • contorller
package com.qian.controller;

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

@Controller
public class EncodingController {
    @RequestMapping("/e1")
    public String test(String name, Model model){
        model.addAttribute("msg",name);
        return "test";
    }
}

当提交的是中文时,会出现乱码

  • 方法一:

使用req的方法解决

  • 方法二:

自定义过滤器来过滤

  • 方法三:

使用spring中的过滤器

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

8、JSON

8.1、什么是JSON

  1. 前后端分离时代:
  • 后端部署后端,提供接口,提供数据
  • 用json进行数据交换
  • 前端独立部署,负责渲染后端的数据;
  1. 什么是JSON?
  • JSON 是一种轻量级的数据交换格式,目前使用特别广泛。
  • 采用完全独立于编程语言的文本格式来存储和表示数据。
  • 简洁和清晰的层次结构使得JSON成为理想的数据交换语言
  • 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
  1. 任何JavaScript支持的类型都可以通过JSON来表示,例如字符串、数字、对象、数组等。JSON的要求和语法格式:
  • 对象表示为键值对,数据由逗号分隔
  • 花括号保存对象
  • 方括号保存数组
{"name":"QINJIANG"}
{"age":"3"}
{"sex":"男"}


  • JSON 是JavaScript对象的字符串表示,它使用文本表示一个JS对象的信息,本质是一个字符串
var obj = {a:'hello',b:'world'};  //这是一个对象

var json = '{"a":"Hello","b":"world"}';  //这是一个JSON字符串,本质就是一个字符串
  1. Json和JavaScript对象互转
  • 从JSON字符串转换为JavaScript对象,使用JSON.parse()方法:

  • 从JavaScript对象转换为JSON字符串,使用JSON.stringify()方法:

 <script type="text/javascript">
      //编写一个JavaScript对象
      var user = {
          name :"秦疆",
          age:3,
          sex:"男"
      }
      console.log(user);
      //1.将js对象转换为json对象
      var json=JSON.stringify(user);
      console.log(json)
      //JSON字符串:{"name":"秦疆","age":3,"sex":"男"}


      //2.将JSON字符串转换为js对象
      var obj = JSON.parse(json);
      console.log(obj)

  </script>

8.2、Jackson使用

  1. Jackson是一个比较好的json解析工具
  • 解析工具不止这一个,比如还有阿里巴巴的fastjson等等
  1. 使用Jackson
  • 导入jar包
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.2.2</version>
</dependency>

  • 配置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>
        <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>
  • 配置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"

>
    <context:component-scan base-package="com.qian.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>

</beans>

  • 编写一个user类
package com.qian.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

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

  • UserController
@Controller
public class UserController {
    @RequestMapping(value = "/j1",produces = "application/json;charset=utf-8")//初步解决乱码问题
    @ResponseBody    //它就不会走视图解析器,而是会直接返回一个字符串
    public String json1() throws JsonProcessingException {
        User user = new User("秦疆1号",3,"男");
        ObjectMapper mapper = new ObjectMapper();
        String str = mapper.writeValueAsString(user);

        return str;
    }
}

  • 乱码统一解决,在springmvc-servlet中配置
<!--    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>
  • @RestController:直接返回一个字符串,不走视图解析器

@RestController 
public class UserController {
    @RequestMapping("/j1")
    public String json1() throws JsonProcessingException {
        User user = new User("秦疆1号",3,"男");
        ObjectMapper mapper = new ObjectMapper();
        String str = mapper.writeValueAsString(user);

        return str;
    }
}
  • json返回多个对象(集合时)
 @RequestMapping("/j2")
    public String json2() throws JsonProcessingException {
        List<User>userList=new ArrayList<User>();
        User user1 = new User("秦疆1号",3,"男");
        User user2 = new User("秦疆1号",3,"男");
        User user3 = new User("秦疆1号",3,"男");
        User user4 = new User("秦疆1号",3,"男");
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);
        ObjectMapper mapper = new ObjectMapper();
        String str = mapper.writeValueAsString(userList);
        //返回集合
        //[{"name":"秦疆1号","age":3,"sex":"男"},{"name":"秦疆1号","age":3,"sex":"男"},{"name":"秦疆1号","age":3,"sex":"男"},{"name":"秦疆1号","age":3,"sex":"男"}]

        return str;
    }
  • 将时间解析
 @RequestMapping("/j3")
    public String json3() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        Date date = new Date();
        String s = mapper.writeValueAsString(date);
        return s;
        //返回一个时间戳  1651719292429
    }

//获取我们可以看懂的日期
 @RequestMapping("/j3")
    public String json3() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        //使用ObjectMapper 来格式化输出
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,false);

        //自定义日期的格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        mapper.setDateFormat(sdf);
        //或者使用 sdf.format来获取
        Date date = new Date();

        String s = mapper.writeValueAsString(date);
        return s;
        //返回一个时间戳  1651719292429
    }
  1. 编写json工具类,可以简化代码,实现复用
package com.qian.utils;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import java.text.SimpleDateFormat;

public class JsonUtils {
    public static String getJson(Object object){
        return getJson(object,"yyyy-MM-dd HH:mm:ss");
    }
    public static String getJson(Object object,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(object);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }
}

  1. FastJson
  • fastjson.jar 是阿里开发的一款专门用于java开发的包,实现json的转换方法很多,最后的实现结果都一样。

  • 导入jar包

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

 @RequestMapping("/j4")
    public String json4() throws JsonProcessingException {
        List<User>userList= new ArrayList<>();
        User user1 = new User("秦疆1号",3,"男");
        User user2 = new User("秦疆2号",3,"男");
        User user3 = new User("秦疆3号",3,"男");
        User user4 = new User("秦疆4号",3,"男");
        userList.add(user1);
        userList.add(user2);
        userList.add(user3);
        userList.add(user4);

        return JSON.toJSONString(userList);

    }
举报

相关推荐

0 条评论