响应
在我们前面的代码例子中, 都已经设置了响应数据Http响应结果可以是数据, 也可以是静态页面, 也可以针对响应设置状态码, Header信息等.
返回静态页面
创建前端页面index.html(注意路径)
html代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello, Spring MVC,我是index页面.
</body>
</html>
后台代码如下:
@RestController
public class IndexController {
@RequestMapping("/index")
public Object index() {
//返回index.html
return "/index.html";
}
}
运行结果:
正确代码如下:
@Controller
public class IndexController {
@RequestMapping("/index")
public Object index() {
//返回index.html
return "/index.html";
}
}
再次运行得到结果:
发现页面正确展示了.
@RestController和@Controller的关系
我们之前讲过了MVC模式, 后端会返回视图, 这是早期时的概念
随着互联网的发展, 目前项目流行"前后端分离模式" , Java主要是用来做后端项目的开发, 所以就不再处理前端相关内容了.
MVC的概念也逐渐发生了变化, View不再返回视图, 而是返回显示视图时所需要的数据.
所以前面的@RestController其实是返回的数据, 是作为一个复合注解.
@RestController = @Controller(默认返回视图) + @ResponseBody(返回数据).
如果想返回视图的话, 只需要把@ResponseBody去掉就可以了, 也就是@Controller.
返回数据@ResponseBody
上面我们讲到, @ResponseBody表示返回数据.
@Controller
@ResponseBody
public class IndexController {
@RequestMapping("/index")
public Object index() {
//返回index.html
return "/index.html";
}
}
加上@ResponseBody注解, 该方法就会把"/index.html"当作一个数据返回给前端.
@Controller
public class IndexController {
@RequestMapping("/index")
public Object index() {
//返回index.html
return "/index.html";
}
@RequestMapping("/returnData")
@ResponseBody
public String returnData() {
return "该方法返回数据";
}
}
如果给第二个方法去掉@Responsebody, 程序就会报404错误.
因为程序会认为返回的应该是视图, 就会根据内容去查找文件, 但是文件查找不到, 路径不存在, 就报404.
返回HTML代码片段
后端返回数据的时候, 如果数据中有HTML代码, 也会被浏览器解析.
@RequestMapping("/returnHtml")
@ResponseBody
public String returnHtml() {
return "<h1>hello HTML~</h1>";
}
运行结果:
通过Fiddler观察结果, Content-Type为 text/html.
返回JSON
Spring MVC也可以返回JSON
后端方法返回结果为对象.
@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;
}
运行结果:
通过Fiddler观察响应结果, Content-Type为application/json.
设置状态码
Spring MVC会根据我们方法的返回结果自动设置响应状态码, 程序员也可以手动指定状态码.
通过Spring MVC的内置对象HttpServletResponse提供的方法来进行设置.
@RequestMapping("/setStatus")
@ResponseBody
public String setStatus(HttpServletResponse response) {
response.setStatus(418);
return "设置状态码成功";
}
运行结果:
通过Fiddler观察设置的结果:
设置Header
Http响应报头也会向客户端传递一些附加信息, 比如服务程序的名称, 请求的资源已移动到新地址等, 如:Content-Type, Local等.
这些信息通过@RequestMapping注解的属性来实现.
先来看@RequestMapping的源码:
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
@Reflective({ControllerMappingReflectiveProcessor.class})
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 {};
}
设置Content-Type
我们通过设置produces属性的值, 设置响应的报头Content-Type.
@RequestMapping(value = "/returnJson2", produces = "application/json")
@ResponseBody
public String returnJson2() {
return "{\"sucess\":true}";
}
运行结果:
Fidder抓包结果:
设置其他Header
设置其它Header的话, 需使用Spring MVC内置对象HttpServletResponse提供的方法来进行设置.
@RequestMapping("/setHeader")
@ResponseBody
public String setHeader(HttpServletResponse response) {
response.setHeader("MyHeader", "MyHeaderValue");
return "设置Header成功";
}
运行成功后查看Fidder抓包结果: