SpringMVC详解
- SpringMVC:SpringMVC的执行流程
- SpringMVC:SSM框架整合
1、回顾MVC
- MVC: 模型(dao,service) 视图(jsp) 控制器(servlet),是一种软件设计规范
- 是将业务逻辑、数据1、显示分离的方法来组织代码
- MVC主要作用是降低了视图与业务逻辑间的双向耦合
- MVC是一种架构模式。
- 假设:问你的项目的架构,是设计好的,还是演进的?
演进的。没有一个项目的架构是一步就能设计好的,都是慢慢演化、进化来的
- 准备工作
- 创建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
- MVC框架要做哪些事情
- 将url映射到java类或java类的方法
- 封装用户提交的数据
- 处理请求–调用相关的业务处理–封装相应数据
- 将响应的数据进行渲染,jsp/html等表示层数据
2、初识SpringMVC
2.1、SpringMVC是什么
- SpringMVC是Spring Framework的一部分,是基于java实现MVC的轻量级web框架
- SpringMvc框架像许多其他MVC框架一样,以请求为驱动,围绕一个中心servlet分派请求及提供其他功能。DispatcherServlet是一个实际的servlet(它继承自HttpServlet基类)
2.2、为什么要学习SpringMVC
- SpringMVC的特点:
- 轻量级,简单易学
- 高效,基于请求响应的MVC框架
- 与Spring兼容性好,无缝结合 (我们可以将SpringMVC需要的所有的bean注册到spring中)
- 约定优于配置
- 功能强大:RESTful、数据验证、格式化、本地化、主题等
- 简洁灵活
- 用的人多,使用的公司也多。
2.3、SpringMVC原理
-
当发起请求时被前置的控制器拦截到请求,根据请求参数生成代理请求,找到请求对应的实际控制器,控制器处理请求,创建数据模型,访问数据库,将模型相应给中心控制器,控制器使用模型与视图渲染视图结果,将结果返回给中心控制器,再将结果返回给请求者。
-
Spring的web框架围绕DispatcherServlet设计,DispatcherServlet的作用是将请求分发到不同的处理器。
-
用户发送请求---->前端控制器(委托请求给处理器)---->页面控制器/处理器(调用业务对象)—>模型(返回模型数据)—>页面控制器/处理器(返回ModelAndView)—>前端控制器(产生响应)—>用户
2.4、Hello,SpringMVC
- 新建一个Moudle,添加web的支持
- 确定导入了SpringMVC的依赖
- 配置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>
- 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>
- 写业务 ,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
- 建一个新的子项目
- 导入静态资源过滤的相关配置
<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>
- 导入相关依赖
- 配置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>
- 配置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>
- 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"; //会被视图解析器处理
}
}
- 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配置总结
- 控制器Controller
- 控制器复杂提供访问应用程序的行为,通常通过接口定义或注解定义(推荐)两种方式实现。
- 控制器负责解析用户的请求并将其转换为一个模型
- 在SpringMVC中一个控制器类可以包含多个方法
4.1、实现Controller接口
- 步骤:
- 实现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>
- 说明:
- 实现接口Controller定义控制器是较老的办法
- 缺点是:一个控制器中只有一个方法,如果要多个方法则需要定义多个Controller;定义的方式比较麻烦
4.3、使用注解@Controller
- @Controller 注解类型用于声明Spring类的实例是一个控制器
- 需要在配置文件中声明组件扫描,自动扫描指定的包,下面所有的注解类交给IOC容器管理
<context:component-scan base-package="com.qian.controller"/>
- 增加一个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说明
- @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风格
- 概念:
- RestFul就是一个资源定位及资源操作的风格。不是标准也不是协议,只是一种风格,基于这个风格设计的软件可以更简介更有层次,更易于实现缓存等机制。
- 功能
-
资源:互联网所有的事物都可以被抽象为资源
-
资源操作:使用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";
}
}
- 使用method属性指定请求类型
@RequestMapping(value = "/add/{a}/{b}",method = {RequestMethod.GET})
- 小结:
- 所有的地址栏请求默认都会是HTTP GET类型的
- 指定请求类型的时候还可以使用组合注解:
@GetMapping
@PostMapping
@DeleteMapping
@PutMapping
- 使用路径变量的好处:
- 使路径变得更加简洁
- 获得参数更加方便,框架会自动进行类型转换
- 通过路径变量的类型可以约束访问参数,如果类型不一样,则访问不到对应的请求方法。
- 安全
6、SpringMVC:结果跳转方式
- 通过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
}
}
- 通过设置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";
}
}
- 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、处理提交数据
- 提交的域名称和处理方法的参数名一致
提交数据: 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";
}
}
- 提交的域名称和处理方法的参数名不一致
提交数据: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加上
- 提交的是一个对象
- 要求提交的表单域和对象的属性名一直,参数使用对象即可
提交数据: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、数据显示到前端
- 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;
}
}
- 通过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";
}
- 通过Model
@Controller
@RequestMapping("/c3")
public class ControllerTest3 {
@RequestMapping("/t1")
public String test3(Model model){
model.addAttribute("msg","你好");
return "test";
}
}
- 对比
- 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
- 前后端分离时代:
- 后端部署后端,提供接口,提供数据
- 用json进行数据交换
- 前端独立部署,负责渲染后端的数据;
- 什么是JSON?
- JSON 是一种轻量级的数据交换格式,目前使用特别广泛。
- 采用完全独立于编程语言的文本格式来存储和表示数据。
- 简洁和清晰的层次结构使得JSON成为理想的数据交换语言
- 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。
- 任何JavaScript支持的类型都可以通过JSON来表示,例如字符串、数字、对象、数组等。JSON的要求和语法格式:
- 对象表示为键值对,数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
{"name":"QINJIANG"}
{"age":"3"}
{"sex":"男"}
- JSON 是JavaScript对象的字符串表示,它使用文本表示一个JS对象的信息,本质是一个字符串
var obj = {a:'hello',b:'world'}; //这是一个对象
var json = '{"a":"Hello","b":"world"}'; //这是一个JSON字符串,本质就是一个字符串
- 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使用
- Jackson是一个比较好的json解析工具
- 解析工具不止这一个,比如还有阿里巴巴的fastjson等等
- 使用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
}
- 编写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;
}
}
- 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);
}