《Spring MVC 响应机制综合实践:页面、数据、JSON 与响应配置》

2.5 响应

在我们前面的代码例子中,都已经设置了响应数据,Http 响应结果可以是数据,也可以是静态页面,也可以针对响应设置状态码,Header 信息等.

2.5.1 返回静态页面

创建前端页面 index.html (注意路径)

后台代码:

java 复制代码
@RestController
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        //返回index.html
        return "/index.html";
    }
}

这个返回的

我们的页面一个返回的是这个

注意:这里没有写这个后面的,只写了一个端口号和本机号,就可以访问index页面

原因如下:

Web 服务器(比如 Tomcat)的默认主页列表 :当访问127.0.0.1:8080(本地服务器)时,服务器会按顺序查找index.htmlindex.jspindex.htm这些文件,找到第一个存在的文件作为默认主页返回。

返回得是字符串没有返回页面得原因如下:

  • @Controller:默认返回视图 (比如跳转 HTML 页面),如果想返回数据,需要额外加@ResponseBody
  • @RestController:默认返回数据 (比如 JSON、字符串),不需要额外加@ResponseBody
特性 @Controller @RestController
核心功能 处理请求,可返回视图 / 数据 处理请求,仅返回数据(JSON / 字符串)
底层构成 单一注解 组合注解(@Controller + @ResponseBody)
视图解析 支持(通过视图解析器) 不支持(返回值直接作为响应体)
典型场景 传统 MVC 页面开发 RESTful API 接口开发

结果却发现,页面未正确返回,http 响应把 "/index.html" 当做了 http 响应正文的数据那 Spring MVC 如何才能识别出来 index.html 是一个静态页面,并进行返回呢?我们需要把 @RestController 改为 @Controller正确代码如下:

java 复制代码
@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        return "/index.html";
    }
}

此时就可以返回视图,也就是我们得页面了

2.5.2 返回数据@ResponseBody

我们上面讲到, @ResponseBody 表示返回数据

java 复制代码
@Controller
@ResponseBody
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        return "/index.html";
    }
}

加上@ResponseBody注解,该方法就会把 "/index.html" 当做一个数据返回给前端.运行:http://127.0.0.1:8080/index

@ResponseBody 既是类注解,又是方法注解

如果作用在类上,表示该类的所有方法,返回的都是数据,如果作用在方法上,表示该方法返回的是数据 .也就是说:在类上添加 @ResponseBody 就相当于在所有的方法上添加了 @ResponseBody 注解.

同样,如果类上有 @RestController 注解时:表示所有的方法上添加了 @ResponseBody 注解,也就是当前类下所有的方法返回值做为响应数据

如果一个类的方法里,既有返回数据的,又有返回页面的,就把 @ResponseBody 注解添加到对应的方法上即可.

代码提取:

java 复制代码
@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        return "/index.html";
    }

    @RequestMapping("/returnData")
    @ResponseBody
    public String returnData(){
        return "该方法返回数据";
    }
}

文本提取:

多个注解时,没有先后顺序,先写哪个都可以运行程序,浏览器响应结果如下:http://127.0.0.1:8080/returnData

如果去掉 @ResponseBody 注解,程序会报 404 错误.

java 复制代码
@Controller
public class IndexController {
    @RequestMapping("/index")
    public Object index(){
        return "/index.html";
    }

    @RequestMapping("/returnData")
    public String returnData(){
        return "该方法返回数据";
    }
}

程序会认为需要返回的是视图,根据内容去查找文件,但是查询不到,路径不存在,报 404

2.5.3 返回HTML代码片段

后端返回数据时,如果数据中有 HTML 代码,也会被浏览器解析

java 复制代码
@RequestMapping("/returnHtml")
@ResponseBody
public String returnHtml() {
    return "<h1>Hello,HTML~</h1>";
}

运行程序,浏览器响应结果如下:http://127.0.0.1:8080/returnHtml

通过Fiddler观察响应结果, Content-Type 为 text/html

如果请求的是 js 文件,Spring MVC 会自动设置 Content-Type 为 application/javascript如果请求的是 css 文件,Spring MVC 会自动设置 Content-Type 为 text/css

java 复制代码
@RequestMapping("/index2")
public Object index2(){
    return "/a.js";
}

@RequestMapping("/index3")
public Object index3(){
    return "/b.css";
}

2.5.4 返回 JSON

Spring MVC 也可以返回 JSON后端方法返回结果为对象

java 复制代码
@RequestMapping("/returnJson")
@ResponseBody
public HashMap<String, String> returnJson() {
    HashMap<String, String> map = new HashMap<>();
    map.put("Java", "Java Value");
    map.put("MySQL", "MySQL Value");
    map.put("Redis", "Redis Value");
    return map;
}

运行程序,浏览器响应结果如下:http://127.0.0.1:8080/returnJson

通过Fiddler观察响应结果, Content-Type 为 application/json

2.5.5 设置状态码

Spring MVC 会根据我们方法的返回结果自动设置响应状态码,程序员也可以手动指定状态码通过 Spring MVC 的内置对象 HttpServletResponse 提供的方法来进行设置

java 复制代码
@RequestMapping(value = "/setStatus")
@ResponseBody
public String setStatus(HttpServletResponse response) {
    response.setStatus(401);
    return "设置状态码成功";
}

通过Fiddler来观察设置的结果

2.5.6 设置 Header (了解)

Http 响应报头也会向客户端传递一些附加信息,比如服务程序的名称,请求的资源已移动到新地址等,如:Content-Type,Local 等.这些信息通过 @RequestMapping 注解的属性来实现先来看 @RequestMapping 的源码

java 复制代码
@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. value: 指定映射的 URL
  2. method: 指定请求的 method 类型,如 GET,POST 等
  3. consumes: 指定处理请求 (request) 的提交内容类型 (Content-Type), 例如 application/json, text/html;
  4. produces: 指定返回的内容类型,还可以同时设置返回值的字符编码
  5. Params: 指定 request 中必须包含某些参数值时,才让该方法处理
  6. headers: 指定 request 中必须包含某些指定的 header 值,才能让该方法处理请求

设置 Content-Type

我们通过设置 produces 属性的值,设置响应的报头 Content-Type

java 复制代码
@RequestMapping(value = "/returnJson2",produces = "application/json")
@ResponseBody
public String returnJson2() {
    return "{\"success\":\"true\"}";
}

运行程序,浏览器响应结果如下:http://127.0.0.1:8080/returnJson2

通过Fiddler来观察设置的结果:

如果不设置produces,⽅法返回结果为String时,

SpringMVC默认返回类型,是text/html. 设置返回类型时,也可以同步设置响应编码

java 复制代码
@RequestMapping(value = "/returnJson2",produces = 
"application/json;charset=utf-8")
@ResponseBody
public String returnJson2() {
return "{\"success\":true}";
}

观察Fiddler的响应结果

设置其他Header

设置其他Header的话,需要使⽤SpringMVC的内置对象HttpServletResponse提供的⽅法来进⾏设置

java 复制代码
@RequestMapping(value = "/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
    response.setHeader("MyHeader","MyHeaderValue");
    return "设置Header成功";
}

void setHeader(String name,String value) 设置一个带有给定的名称和值的 header. 如果 name 已经存在,则覆盖旧的值.

运行程序,浏览器响应结果如下: http://127.0.0.1:8080/setHeader

补充说明

  • 功能作用 :通过HttpServletResponsesetHeader()方法,可自定义 HTTP 响应头(键值对形式),常用于传递额外的响应元信息(如自定义标识、权限令牌等)。
  • 覆盖规则:若重复设置同名响应头,后设置的值会覆盖之前的值。

运⾏程序,浏览器响应结果如下: http://127.0.0.1:8080/setHeader

通过Fiddler来观察设置的结果

相关推荐
JHC0000002 小时前
dy直播间评论保存插件
java·后端·python·spring cloud·信息可视化
SuperherRo2 小时前
JAVA攻防-FastJson专题&面试不出网利用&BCEL字节码&C3P0二次&Impl链&延时判断
java·fastjson·不出网
TH_12 小时前
18、删除WPSOfficeWord文档中的空白页
java
一雨方知深秋2 小时前
数组定义及访问
java·数组·二维数组·for·length·定义访问
alanesnape2 小时前
Java异常处理详解:Exception、ArithmeticException、FileNotFoundException
java·开发语言
while(1){yan}2 小时前
数据链路层与物理层
java·网络·网络协议
野蛮人6号2 小时前
黑马微服务 p23Docker02 docker的安装 如何正确安装docker,黑马微服务给的文档不行了,如何正确找到解决方法
java·docker·微服务·架构
武子康2 小时前
Java-206 RabbitMQ 发布订阅(fanout)Java 实战:推/拉模式、ACK 与绑定排错全梳理
java·分布式·消息队列·rabbitmq·rocketmq·java-rabbitmq·mq