资讯动态

Java EE 进阶:4.Spring Web MVC 入门(第三弹)

发布时间:2026/10/23 4:54:13 来源:尧图企业网站定制
目录2.5 响应2.5.1 返回静态页面RestController 和 Controller 的关联及区别2.5.2 返回数据ResponseBody小结2.5.3 返回 HTML 代码片段2.5.4 返回 JSON2.5.5 设置状态码2.5.6 设置 Header了解设置 Content-Type课件内容设置其他 Header课件内容书接上文Java EE 进阶4.Spring Web MVC 入门第二弹~~2.5 响应在我们前面的代码例子中都已经设置了响应数据, Http响应结果可以是数据, 也可以是静态页面,也可以针对响应设置状态码, Header信息等.2.5.1 返回静态页面创建前端页面 index.html(注意路径)html代码如下:!DOCTYPE html html langen head meta charsetUTF-8 titleTitle/title /head body h1我是Index/h1 /body /html比如说用户登录之后我想给用户返回这个静态页面后台代码:package com.bite.spring.demo; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; RequestMapping(/resp) RestController public class RespController { RequestMapping(r1) public String returnPage(){ return index.html; } }运行结果:http://127.0.0.1:8080/resp/r1结果却发现, 页面未正确返回, http响应把index.html 当做了http响应正文的数据那Spring MVC如何才能识别出来 index.html 是一个静态页面, 并进行返回呢?我们需要把 RestController 改为 Controller再来尝试一下package com.bite.spring.demo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; RequestMapping(/resp) Controller public class RespController { RequestMapping(r1) public String returnPage(){ return index.html; } }再次运行: http://127.0.0.1:8080/resp/r1原因是没有加 /下面是正确代码package com.bite.spring.demo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; RequestMapping(/resp) Controller public class RespController { RequestMapping(r1) public String returnPage(){ return /index.html; } }发现页面正确展示了闲聊啥时候加 / 啥时候不加 / 呢个人理解就是前端不加后端加当然这只是个人感觉不是很权威一切以运行结果为准~~如果我们把它再加一层路径的话后端代码也必须相应加一层后端代码RequestMapping(/resp) Controller public class RespController { RequestMapping(r1) public String returnPage(){ return /aa/index.html; } }所以前端路径是从 static 下面往下数有几层就写几层~~RestController 和 Controller 的关联及区别当时我们说 RestController 是帮助我们快速扫描代码因为代码太多了下面都是我们的代码只是不用我们写直接拿人家写好了的用这其中任何一个出现问题都会直接影响我们的使用但是全部扫描一遍又太耗时间了所以我们用 RestController 快速定位到需要扫描的代码下面注意SpringBoot 默认扫描路径为 启动类所在的路径及其子目录如果我们新建一层路径 aa将启动类放进去我们会发现我们之前的所有代码在启动服务后都运行不了了浏览器结果Postman 结果下面我们再把 启动类改回来将其他代码放进去看看浏览器结果Postman 结果其他代码放在 启动类所在路径的子目录下依然能够被访问到也验证了我们的结论~~那 Controller 又是啥先给结论RestController ResponseBody Controller这是一个复合注解下面我们来看一下注解 RestController 的构成①Target这个注解可以放在哪里上述 RestController 就只能放在类上放在方法上就会报错这个属性就决定了有的可以放在类上有的可以放在方法上也有的可以放在参数上而 RequestMapping 既可以放在类上又可以放在方法上就是因为而 RequestParam 可以放在参数上也是因为这个②Retention注解的生命周期我们都知道Java 代码运行有几个阶段第一个是源码阶段就是我们现在的阶段我们启动的时候就要进行编译编译之后才是运行只不过我们通过 IDEA 就看不到编译的过程了其实下面的 classes 就是编译的结果注解的生命周期总共有三个源码→class→runtime运行时期如果只是标识 Source代表你只能从源码阶段看到它在 class 阶段你就看不到它了它就消失了Class 时期 和 runtime 时期也类似~~③Documented文档这个我们不用了解知道就行了所以 RestController 和 Controller 就只是差在ResponseBody 上了ResponseBody返回数据闲聊ResponseBody 这就与我们的历史有关系了~~早期的时候“前后端不分家”咱们前面讲了MVC模式, 后端会返回视图, 这是早期时的概念像前面这行代码其实就是返回的视图return /aa/index.html;随着互联网的发展, 目前项目开发流行前后端分离模式, Java主要是用来做后端项目的开发, 所以也就不再处理前端相关的内容了MVC的概念也逐渐发生了变化, View不再返回视图, 而是返回显示视图时需要的数据.所以前面使用的RestController 其实是返回的数据.Controller : 定义一个控制器, Spring 框架启动时加载, 把这个对象交给Spring管理.ResponseBody : 定义返回的数据格式为非视图, 返回一个 text/html 信息如果想返回视图的话, 只需要把ResponseBody 去掉就可以了, 也就是Controller在早期的时候我们后端只是返回页面视图但是现在的话我们就直接返回数据了跟页面没关系了前端的页面前端爱咋整咋整~~2.5.2 返回数据ResponseBody我们上面讲到, ResponseBody 表示返回数据.如果你想返回页面的话就得使用 Controller那么我现在又想返回数据又想返回页面返回数据就要用到 RestController于是代码就变成了这样package com.bite.spring.demo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; RequestMapping(/resp) //RestController Controller public class RespController { /** * 返回页面 * return */ RequestMapping(r1) public String returnPage(){ return /aa/index.html; } /** * 返回数据 * return */ RequestMapping(r2) public String returnData(){ return 我是前端需要的数据; } }此时我们依次尝试一下r1没有问题r2404为啥会报 404因为它认为这是一个页面它去找这个页面但是没找到所以报错了接下来咋办一个要 RestController一个要 Controller两者相减就等于 ResponseBody加上它表示该方法返回的是一个数据所以我们的代码是package com.bite.spring.demo; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; RequestMapping(/resp) //RestController Controller public class RespController { /** * 返回页面 * return */ RequestMapping(r1) public String returnPage(){ return /aa/index.html; } /** * 返回数据 * return */ ResponseBody RequestMapping(r2) public String returnData(){ return 我是前端需要的数据; } }接下来再观察一下r1没问题r1没问题小结①如果一个类既返回页面又返回数据类上使用 Controller在返回数据的方法上加 ResponseBodyController public class RespController { /** * 返回页面 * return */ RequestMapping(r1) public String returnPage(){ return /aa/index.html; } /** * 返回数据 * return */ ResponseBody RequestMapping(r2) public String returnData(){ return 我是前端需要的数据; } }②如果一个类全部返回数据可以使用 RestController 或者 ResponseBody Controller或者ResponseBody 既是类注解, 又是方法注解如果作用在类上表示该类的所有方法, 返回的都是数据,如果作用在方法上表示该方法返回的是数据.也就是说: 在类上添加ResponseBody 就相当于在所有的方法上添加了ResponseBody 注解.同样, 如果类上有RestController 注解时表示所有的方法上添加了ResponseBody 注解, 也就是当前类下所有的方法返回值做为响应数据③如果一个类全部返回页面使用 Controller答疑Q1可以一次发起两个请求不指的是 http 请求嘛这是不可以的因为这是客户端就像你一个人多开两个网页的话那就不叫一次了如果说同时发起两个请求的话可以两个用户一起发送或者借助一些工具~~其实说白了就是多创建了几个线程而已后面学习测试的时候会学到用一些工具同时发送多个请求~~Q2全部返回数据只用 ResponseBody 可以吗不可以需要加上 Controller这个是必须要加的2.5.3 返回 HTML 代码片段如果前端的一些图标是由后端来返的那么后端就需要给返回一个 HTML 片段但是也非常非常少啊因为后端现在不做前端了但是还是给大家讲一讲了解一下而已后端返回数据时, 如果数据中有HTML代码, 也会被浏览器解析ResponseBody RequestMapping(r3) public String returnHTML(){ return h1我是一级标题/h1; }运行程序, 浏览器响应结果如下:http://127.0.0.1:8080/resp/r3通过Fiddler观察响应结果, Content-Type 为text/htmlContent-Type 是 text/html 类型时会自动解析我们返回数据的 HTML 片段就会把它作为 HTML 去解析的如果你想返回片段的话默认情况下就可以满足那如果不想让它去解析我这就是一个正儿八经的数据我的内容就是 h1咋让它去返回由于上面说了解析的原因就是 Content-Type 是 text/html 类型那么我们把 text/html 改一下就可以了ResponseBody RequestMapping(value r4,produces text/plain) public String returnText(){ return h1我是一级标题/h1; }这次结果就变成一个数据了差异就在这响应中的 Content-Type 常见取值有以下几种:• text/html : body 数据格式是 HTML• text/plain : body 数据格式是 纯文本格式• text/css : body 数据格式是 CSS• application/javascript : body 数据格式是 JavaScript• application/json : body 数据格式是 JSON• multipart/form-data需要在表单中进行文件上传时就需要使用该格式如果请求的是js文件, Spring MVC会自动设置Content-Type为application/javascript如果请求的是css文件, Spring MVC会自动设置Content-Type为text/css闲聊学过 Servlet 的都知道Servlet 就非常麻烦需要自己去设置它的 Content-Type还有编码都需要设置但是 我们的 Spring 的这些都不用设置默认情况下都给我们设置好了但是特殊情况下比如乱码就需要自己再设置一下了2.5.4 返回 JSONSpring MVC 也可以返回JSON后端方法返回结果为对象ResponseBody RequestMapping(value /r5) public UserInfo returnJson(){ UserInfo userInfonew UserInfo(CoderYanger,21,1); return userInfo; }运行程序, 浏览器响应结果如下: http://127.0.0.1:8080/resp/r5通过Fiddler观察响应结果, Content-Type 为 application/json可能在我们后端看起来都是一样的但是对于前端就是不同的如果是 JSON那么前端就可以直接转成对象处理当对象来使用如果是文本的话那前端就需要再处理一下才能把这个字符串转成对象如果用 Postman 的话就直接转成 JSON 了答疑这代码返回的不是一个对象吗为啥是一个 JSON我们的 HTTP 没办法设置对象我们来简单回顾一下 HTTP 的 Content-Type 类型• text/html : body 数据格式是 HTML• text/plain : body 数据格式是 纯文本格式• text/css : body 数据格式是 CSS• application/javascript : body 数据格式是 JavaScript• application/json : body 数据格式是 JSON• multipart/form-data需要在表单中进行文件上传时就需要使用该格式我们的 Content-Type 分为两种一个是 Request Content-Type 一个是 Response Content-Type 一个是请求的一个是响应的而这时我们返回的 UserInfo 一定是响应的所以在查资料的时候一定要分清是 Request 的还是 Response 的也就是说我们虽然返回了 UserInfo 对象但是我们没有任何一个 Content-Type 类型可以表示对象的我们所谓的这个对象只是 Java 的格式包括我们返回的 List、Map这都是我们 Java 的格式我们的前端如何识别对于这种对象全部返回 JSON所以说 List、Map 还有一些更复杂的其他格式的对象Spring 返回的都是 JSON 这样前端就能识别为对象了~~2.5.5 设置状态码Spring MVC会根据我们方法的返回结果自动设置响应状态码, 程序员也可以手动指定状态码通过Spring MVC的内置对象HttpServletResponse 提供的方法来进行设置ResponseBody RequestMapping(value /r6) public UserInfo setStatus(HttpServletResponse response){ response.setStatus(404); UserInfo userInfonew UserInfo(CoderYanger,21,1); return userInfo; }运行程序, 浏览器响应结果如下: http://127.0.0.1:8080/resp/r6状态码不影响页面的展示所以我们的页面并未发生变化~~通过Fiddler来观察设置的结果:那这是咋回事儿正常的 404 不应该是这样吗其实状态码和页面的展示是没有关系的~~至于上面的那个错误页面是 Spring 默认设置的正如 B 站的 404 也是自己设置的下面的前端代码就是这个漂亮 404 的界面代码而这个状态码不是只是后端用前端也要根据你这个状态码来对应做一些处理的~~2.5.6 设置 Header了解有时候前端也会根据 Header 去做一些处理~~ResponseBody RequestMapping(value /r7) public String setHeader(HttpServletResponse response){ response.setHeader(myHeader,myHeader); return 设置Header成功; }此时抓包就可以看到我们自己设置的 Header 了当我不希望它通过正文返回时就可以设置让其从 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: 指定映射的URL2. produces: 响应指定返回的内容类型还可以同时设置返回值的字符编码这个大家记一下就可以了~~就是我们之前的以下都是请求相关的3. method: 指定请求的method类型, 如GET, POST等4. consumes: 指定处理请求(request)的提交内容类型(Content-Type)例如application/json,text/html;5. Params: 指定request中必须包含某些参数值时才让该方法处理6. headers: 指定request中必须包含某些指定的header值才能让该方法处理请求了解即可, 更多说明参考 Mapping Requests :: Spring Framework设置 Content-Type课件内容我们通过设置 produces属性的值, 设置响应的报头Content-TypeRequestMapping(value /returnJson2,produces application/json) ResponseBody public String returnJson2() { return {\success\:true}; }运行程序, 浏览器响应结果如下: http://127.0.0.1:8080/returnJson2通过Fiddler来观察设置的结果:如果不设置produces , 方法返回结果为String时, Spring MVC默认返回类型, 是text/html.设置返回类型时, 也可以同步设置响应编码RequestMapping(value /returnJson2,produces application/json;charsetutf-8) ResponseBody public String returnJson2() { return {\success\:true}; }观察Fiddler的响应结果设置其他 Header课件内容设置其他Header的话, 需要使用Spring MVC的内置对象HttpServletResponse 提供的方法来进行设置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通过Fiddler来观察设置的结果:

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑