【JavaEE】深入浅出:服务器如何响应Web请求


4. 响应

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

返回静态页面

用到@Controller

创建前端⻚⾯ index.html(注意路径)

在这里插入图片描述

找到启动类,启动

@SpringBootApplication就是启动类

后端代码

@RequestMapping("/return")
@RestController
public class ReturnController {
    @RequestMapping("/index")
    public String returnIndex(){
        return "/index.html";
    }
}

如果只是这样写

在这里插入图片描述

结果却发现, ⻚⾯未正确返回, http响应把 "/index.html" 当做了http响应正⽂的数据

那Spring MVC如何才能识别出来 index.html 是⼀个静态⻚⾯, 并进⾏返回呢?

我们需要把 @RestController 改为 @Controller

@RequestMapping("/return")
//@RestController
@Controller
public class ReturnController {
    @RequestMapping("/index")
    public String returnIndex(){
        return "/index.html";
    }
}

改成这样,把@RestController改成@Controller

在这里插入图片描述

此时返回的就是页面了

@RestController@Controller 有着什么样的关联和区别呢?

前⾯讲了MVC模式, 后端会返回视图, 这是早期时的概念

在这里插入图片描述

随着互联⽹的发展, ⽬前项⽬开发流⾏"前后端分离"模式, Java主要是⽤来做后端项⽬的开发, 所以也就不再处理前端相关的内容了

MVC的概念也逐渐发⽣了变化, View不再返回视图, ⽽是返回显⽰视图时需要的数据

所以前⾯使⽤的 @RestController 其实是返回的数据.

@RestController = @Controller + @ResponseBody

@Controller : 定义⼀个控制器, Spring 框架启动时加载, 把这个对象交给Spring管理.

@ResponseBody : 定义返回的数据格式为⾮视图, 返回⼀个 text/html 信息

@RestController 源码:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
	@AliasFor(
		annotation = Controller.class
	)
	String value() default "";
}

如果想返回视图的话, 只需要把 @ResponseBody 去掉就可以了, 也就是 @Controller

上面三个注解:

  1. @Target({ElementType.TYPE}),表示注解修饰的是什么,这里的TYPE表示就是可以修饰类、接口
  2. @Retention(RetentionPolicy.RUNTIME),表示注解的生命周期,这里的RUNTIME表示运行阶段,还有SOURCECLASS,前者表示源代码活在代码阶段,编译之后就消失了、后者表示编译阶段
  3. @Documented,表示文档要不要保留,比如注释这些

这三个称为元注解:可以被其他注解使用的注解称为元注解

返回数据

@ResponseBody 表⽰返回数据

@ResponseBody
@RequestMapping("/returnData")
public String returnData(){
    return "返回视图需要的数据";
}

加上 @ResponseBody 注解, 该⽅法就会把 “返回视图需要的数据” 当做⼀个数据返回给前端

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

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

运行http://127.0.0.1:8080/return/returnData

在这里插入图片描述

@ResponseBody 既是类注解, ⼜是⽅法注解

如果作⽤在类上, 表⽰该类的所有⽅法, 返回的都是数据, 如果作⽤在⽅法上, 表⽰该⽅法返回的是数据.

也就是说: 在类上添加 @ResponseBody 就相当于在所有的⽅法上添加了 @ResponseBody 注解

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

如果⼀个类的⽅法⾥, 既有返回数据的, ⼜有返回⻚⾯的, 就把 @ResponseBody 注解添加到对应的⽅法上即可.

多个注解时, 没有先后顺序, 先写哪个都可以

返回HTML代码片段

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

@ResponseBody
@RequestMapping("/returnHtml")
public String returnHtml(){
    return "<h1>返回HTML片段<h1>";
}

运行http://127.0.0.1:8080/return/returnHtml

在这里插入图片描述

响应中的 Content-Type 常⻅取值有以下⼏种:

  • text/html : body 数据格式是 HTML
  • text/css : body 数据格式是 CSS
  • application/javascript : body 数据格式是 JavaScript
  • application/json : body 数据格式是 JSON

如果请求的是js⽂件, Spring MVC会⾃动设置Content-Type为 application/javascript

如果请求的是css⽂件, Spring MVC会⾃动设置Content-Type为 text/css

返回JSON

Spring MVC 也可以返回JSON

后端⽅法返回结果为对象

@ResponseBody
@RequestMapping("/returnJson")
public Person returnJson(){
    Person person=new Person();
    person.setId(1);
    person.setName("zhangsan");
    person.setAge(7);
    return person;
}

运行http://127.0.0.1:8080/return/returnJson

在这里插入图片描述

通过fiddler观察

在这里插入图片描述

当我们的接口返回的是String时,content-Type是text/html

当我们的接口返回的是对象时,content-Type自动设置为application/json

当我们的接口返回的是Map时,content-Type也自动设置为application/json

设置状态码

Spring MVC会根据我们⽅法的返回结果⾃动设置响应状态码, 程序员也可以⼿动指定状态码

通过Spring MVC的内置对象 HttpServletResponse 提供的⽅法来进⾏设置

@ResponseBody
@RequestMapping("/setStatus")
public String setStatus(HttpServletResponse response){
    response.setStatus(401);//通常表示没有登录
    return "设置状态码";
}

运行http://127.0.0.1:8080/return/setStatus

在这里插入图片描述

在这里插入图片描述

状态码不影响页面的展示

上面的是Http状态码

设置Header

这部分了解即可,这部分是响应的Header

Http响应报头也会向客⼾端传递⼀些附加信息, ⽐如服务程序的名称,请求的资源已移动到新地址等, 如:Content-Type, Local等

这些信息通过 @RequestMapping 注解的属性来实现:

先来看 @RequestMapping 的源码:

@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: 设置返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回

  5. Params: 指定request中必须包含某些参数值时,才让该⽅法处理

  6. headers: 指定request中必须包含某些指定的header值,才能让该⽅法处理请求

了解即可, 更多说明参考

https://docs.spring.io/spring-framework/reference/web/webmvc/mvc-controller/ann-requestmapping.html#mvc-ann-requestmapping-consumes

设置Content-Type

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

@ResponseBody
@RequestMapping(value = "/r1")
public String r1(HttpServletResponse response){
    return "{'OK':1}";
}

如果是这么写的话,通过fiddler观察仍是text/html

在这里插入图片描述

@ResponseBody
@RequestMapping(value = "/r1",produces = "application/json;charset=utf8")
public String r1(HttpServletResponse response){
    return "{'OK':1}";
}

如果是这么写的话就可以修改了,但要注意也是要匹配了才能修改,不能乱改

在这里插入图片描述

设置其他Header

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

@ResponseBody
@RequestMapping(value = "/r2",produces = "application/json;charset=utf8")
public String r2(HttpServletResponse response){
    response.setHeader("myheader","123456");
    return "{'OK':1}";
}

在这里插入图片描述

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值