七、springMVC之返回JSON和静态文件访问
一、概述
1.目录结构:
2.配置方式:
web.xml:配置DispacherServlet ;参考SpringMVC之HelloWorld;
spring.xml配置了 包的扫描、视图解析器、<mvc:annotation-driven>和静态文件的访问配置(<mvc:default-servlet-handler />)

1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:mvc="http://www.springframework.org/schema/mvc" 5 xmlns:context="http://www.springframework.org/schema/context" 6 xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd 7 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 8 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 9 10 <context:component-scan base-package="handler"></context:component-scan> 11 <!-- 配置视图解析器 如何把handler 方法返回值解析为实际的物理视图 --> 12 <bean 13 class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 14 <property name="prefix" value="/"></property> 15 <property name="suffix" value=".jsp"></property> 16 </bean> 17 <mvc:annotation-driven></mvc:annotation-driven> 18 19 <mvc:default-servlet-handler /> 20 </beans>
二、实例验证
步骤:
- 需要加入3个jar包;jackson-annotations jackson-core,jackson-databind<br>
- 编写目标方法,使其返回json对应的对象的集合
- 方法上加入@ResponseBody注解
1.实体类Employee.java

1 package handler.entity; 2 3 import java.util.Date; 4 5 public class Employee { 6 private int id; 7 private String name; 8 private String gender; 9 private String email; 10 private float salary; 11 private Date birthDay; 12 13 public int getId() { 14 return id; 15 } 16 17 public void setId(int id) { 18 this.id = id; 19 } 20 21 public String getName() { 22 return name; 23 } 24 25 public void setName(String name) { 26 this.name = name; 27 } 28 29 public String getGender() { 30 return gender; 31 } 32 33 public void setGender(String gender) { 34 this.gender = gender; 35 } 36 37 public Date getBirthDay() { 38 return birthDay; 39 } 40 41 public void setBirthDay(Date birthDay) { 42 this.birthDay = birthDay; 43 } 44 45 public String getEmail() { 46 return email; 47 } 48 49 public void setEmail(String email) { 50 this.email = email; 51 } 52 53 public float getSalary() { 54 return salary; 55 } 56 57 public void setSalary(float salary) { 58 this.salary = salary; 59 } 60 61 @Override 62 public String toString() { 63 return "Employee [id=" + id + ", name=" + name + ", gender=" + gender + ", email=" + email + ", salary=" 64 + salary + ", birthDay=" + birthDay + "]"; 65 } 66 67 }
2.控制器方法EmployeeController.java:
方法上面添加了@RequestBody,且返回值为list;
1 package handler; 2 3 import java.util.ArrayList; 4 import java.util.Calendar; 5 import java.util.List; 6 7 import org.springframework.stereotype.Controller; 8 import org.springframework.web.bind.annotation.RequestMapping; 9 import org.springframework.web.bind.annotation.ResponseBody; 10 11 import handler.entity.Employee; 12 13 @RequestMapping("/emp") 14 @Controller 15 public class EmployeeController { 16 17 @ResponseBody 18 @RequestMapping("/testJson") 19 public List<Employee> testJSON() { 20 List<Employee> list = new ArrayList<Employee>(); 21 Calendar calendar = Calendar.getInstance(); 22 calendar.set(Calendar.YEAR, 1991); 23 String[] arr = { "Tom", "Jerry", "John", "Joy", "Lucy", "Alice" }; 24 for (int i = 0; i < 5; i++) { 25 calendar.set(Calendar.DATE, (i + 1)); 26 Employee employee = new Employee(); 27 employee.setBirthDay(calendar.getTime()); 28 employee.setEmail(arr[i] + "@163.com"); 29 employee.setGender(i % 2 == 0 ? "0" : "1"); 30 employee.setId(i + 1); 31 employee.setName(arr[i]); 32 employee.setSalary(i * 100); 33 list.add(employee); 34 } 35 return list; 36 } 37 38 }
3.测试页面index.jsp:
页面引入了jQuery,所以对应的spring.xml 配置了静态文件访问;default-servlet-handler 将在springMVC上下文中定义一个DefaultServletHttpRequestHandler,
它会对进入DpatcherServlet的请求进行筛查,如果发现没有经过映射的请求,就把该请求交给web应用服务默认的 servlet 处理。如果不是静态请求,才由DpatcherServlet继续处理

1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <%@page import="java.util.*"%> 4 <!DOCTYPE html> 5 <html> 6 <head> 7 <meta charset="UTF-8"> 8 <title>Insert title here</title> 9 <script type="text/javascript" src="./js/jquery.min.js"></script> 10 </head> 11 <body> 12 <a id="testJson">TEST JSON</a> 13 <div id="jsonContent"></div> 14 </body> 15 <script type="text/javascript"> 16 $(function(){ 17 $("#testJson").click(function(){ 18 $.post("${pageContext.request.contextPath}/emp/testJson",{},function(data){ 19 var str=""; 20 for (var i = 0; i < data.length; i++) { 21 str += "<span>" + data[i].name+","+ data[i].email+","+ data[i].gender+ "</span><br>"; 22 } 23 $("#jsonContent").append(str); 24 }) 25 }) 26 }) 27 </script> 28 </html>
4.运行结果
访问index.jsp页面,点击TEST JSON 会显示 后台传入的employee 列表的值,该列表的值是JSON格式的,如下图所示;
三、相关注解
1.HttpEntity /ResponseEntity
ResponseEntity的优先级高于@ResponseBody。在不是ResponseEntity的情况下才去检查有没有@ResponseBody注解。如果响应类型是ResponseEntity可以不写@ResponseBody注解,写了也没有关系。
ResponseEntity 是在 org.springframework.http.HttpEntity 的基础上添加了http status code(http状态码),用于RestTemplate以及@Controller的HandlerMethod。它在Controoler中或者用于服务端响应时,作用是和@ResponseStatus与@ResponseBody结合起来的功能一样的。用于RestTemplate时,它是接收服务端返回的http status code 和 reason的。
总结:简单粗暴的讲 @ResponseBody可以直接返回Json结果, @ResponseEntity不仅可以返回json结果,还可以定义返回的HttpHeaders和HttpStatus
使用参考实例:

1 @RequestMapping("/testResponseEntity") 2 public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException { 3 byte[] body = null; 4 ServletContext servletContext = session.getServletContext(); 5 InputStream in = servletContext.getResourceAsStream("/file/test.json"); 6 body = new byte[in.available()]; 7 in.read(body); 8 HttpHeaders headers = new HttpHeaders(); 9 headers.add("Content-Disposition", "attachment;filename=abc.txt"); 10 HttpStatus status = HttpStatus.OK; 11 ResponseEntity<byte[]> response = new ResponseEntity<byte[]>(body, headers, status); 12 return response; 13 }
2.@ResponseBody
用法:放在controller层的方法上;
将Controller的方法返回的对象,SpringMVC会根据返回值类型(Map、Llist)找到可以处理的消息转换器,并确定结果的MediaType。返回对象、map和List结果将由MappingJackson2HttpMessageConverter处理,并且MediaType为:application/json。后面写入到Response对象的body数据区。
使用时机:
当我们想让页面知道我们返回的数据不是按照html标签的页面来解析,而是其他某种格式的数据解析时(如json、xml等)使用。

1 @RequestMapping("/getList") 2 @ResponseBody 3 public Map<String,Object> getStudentList(HtppServletRequest request){ 4 Map<String,Object> map=new HashMap<String,Object>(); 5 Dto dto=getParamAsDto(request); 6 List li=studentAction.getList(dto.get("age")); 7 map.put("studentInfo",li); 8 }
3.@RequestBody
用法:一般放在controller层的具体请求方法的入参中。比如:

1 @PostMapping("/url") 2 public urlBo getUrlByPhoneNumber(@RequestBody String json,HttpServetRequest request){ 3 UrlBo ub=new Gson().fromJson(json,UrlBo.class); 4 ....//其他处理逻辑 5 }
这里的@RequestBody用于读取Http请求的body部分数据——就是我们的请求数据。比如json或者xml。然后把数据绑定到 controller中方法的参数上,这里就是String json这个入参啦~。
使用时要注意能不能用@RequestBody把request请求的数据解析,并赋给我们定义的参数上是由请求头的Content-Type的值来决定的。
当我们用get/post方式提交请求后, Content-Type的值有以下几种,分别对应能不能解析数据如下:
Content-Type数据格式 | @RequestBody是否必须 | 备注 |
application/x-www-form-urlencoded | 可选 |
这种情况的数据@RequestParam, @ModelAttribute也可以处理,当然@RequestBody也能处理; 这种格式的特点就是,name/value 成为一组,每组之间用 & 联接,而 name与value 则是使用 = 连接 如:a=1&b=2 |
multipart/form-data | 不能处理 | 即使用@RequestBody不能处理这种格式的数据 |
其他格式(比如application/json, application/xml) | 必须 | 必须使用@RequestBody来处理 |
参考地址:https://www.cnblogs.com/lixiuming521125/p/7885741.html#_label0
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通