SpringMVC4
一、SpringMVC 注解与项目开发流程
1.1注解的生命周期
- @Target、@Retention 等元注解:
- @Target(ElementType.TYPE) :说明这个注解只能用在类、接口上。
- @Retention(RetentionPolicy.RUNTIME) :说明注解在运行时保留,能通过反射获取。
- @Documented :生成文档时包含这个注解。
- @Controller 、 @ResponseBody :这两个注解组合起来就是 @RestController ,所以 @RestController = @Controller + @ResponseBody 。
- @RestController 接口示例:
public @interface RestController {
@AliasFor(annotation = Controller.class)
String value() default "";
}
- @AliasFor :指定 value 属性和 @Controller 的 value 属性互为别名。
@ResponseBody 注解
- 作用:把方法返回值转成 JSON 或字符串,直接返回给客户端,而不是跳转到页面。
- 示例 1(返回字符串):
@ResponseBody
@RequestMapping("/returnHTML")
public String returnHTML() {
return "<h1>returnHTML</h1>";
}
- 方法返回字符串 <h1>returnHTML</h1> ,会直接作为响应体返回给客户端(浏览器会把它当 HTML 渲染)。
- 示例 2(设置响应头和响应体):
@ResponseBody
@RequestMapping("/setContentType")
public void setContentType(HttpServletResponse response) throws IOException {
response.setContentType("text/html"); // 设置响应类型为 HTML
response.getOutputStream().write("<h1>setContentType</h1>".getBytes(StandardCharsets.UTF_8));
}
- HttpServletResponse :用来设置响应头、响应体等。这里设置 Content-Type 为 text/html ,然后写响应体。
@RequestMapping 注解的属性
- value:指定映射的 URL 路径,是默认属性。
- method:指定支持的请求方法(GET、POST 等)。
- consumes:指定请求体的 MIME 类型(比如 application/json ),只有符合的请求才会被处理。
- produces:指定响应体的 MIME 类型(比如 application/json ),设置返回的 Content-Type 。
- params:指定请求中必须包含某些参数,才会被处理。
- headers:指定请求头中必须包含某些值,才会被处理。
1.2国内企业主流开发模式(前后端分离)
- 前后端代码完全分开:前端代码(Vue、React 等)和后端代码(SpringBoot 等)在不同项目里,甚至不同团队开发。
- 部署方式:前端单独部署(比如用 Nginx),后端也单独部署(比如用 Tomcat、Jar 包)。
- 对比课堂案例:课堂里的案例前后端没完全分离,前端页面在后端项目里(比如 static/index.html )。
- 微服务模式:更彻底的分离,每个服务独立开发、部署、运维。
1.3项目开发流程
1. 需求调研:和 PM(产品经理)、业务方沟通,明确需求文档(目标、功能、逻辑等)。
2. 分工干活:
- 方案设计:概要设计、详细设计、数据库设计、接口设计。
- 方案 review:团队评审方案,发现问题及时改。
- 开发:写代码实现功能。
- 自测:开发自己测试,保证功能没问题。
3. 提测:把功能交给测试人员测试。
4. 联调:前后端、服务间联调,保证整个流程跑通。
5. 上线:把代码部署到生产环境。
- 接口文档:企业开发中,接口文档一般一次性全部提供;课堂里是一个接口一个接口提供。
- 敏捷开发:尽量做到短期交付(比如两周一个迭代),别 delay。
二、Session、请求头与返回页面
2.2Session 的工作流程
1. 客户端发请求:第一次请求时,服务器还没给客户端分配 Session。
2. 服务器创建 Session:服务器生成 Session,把 SessionID 通过 Set-Cookie 头返回给客户端。
3. 客户端带 Cookie 发请求:后续请求时,客户端会自动带上包含 SessionID 的 Cookie。
4. 服务器查 Session:服务器根据 SessionID 找到对应的 Session,处理请求(比如获取用户信息)。
- Session 存储:默认存在服务器内存里,服务器重启后 Session 就没了(可以用 Redis 等持久化 Session)。
2.2request.getSession() 方法
- request.getSession():
- 默认 create = true ,如果没有 Session,就创建一个新的。
- 示例:
@RequestMapping("/getSession")
public String getSession(HttpServletRequest request) {
HttpSession session = request.getSession(); // 没有就创建
String name = (String) session.getAttribute("name");
Integer age = (Integer) session.getAttribute("age");
return "Session 中的数据,name: " + name + ",age: " + age;
}
- request.getSession(false):
- create = false ,如果没有 Session,就返回 null ,不创建新的。
- 示例:
@RequestMapping("/getSession2")
public String getSession2(HttpServletRequest request) {
HttpSession session = request.getSession(false); // 没有就返回 null
if (session == null) {
return "没有 Session";
}
String name = (String) session.getAttribute("name");
Integer age = (Integer) session.getAttribute("age");
return "Session 中的数据,name: " + name + ",age: " + age;
}
2.3请求头相关(@RequestHeader)
- @RequestHeader:从请求头中取参数。
- 示例 1(取单个请求头):
@RequestMapping("/getHeader")
public String getHeader(HttpServletRequest request) {
String userAgent = request.getHeader("User-Agent");
return "Header 中的数据,User-Agent: " + userAgent;
}
- 示例 2(用 @RequestHeader 注解):
@RequestMapping("/getHeader2")
public String getHeader2(@RequestHeader("User-Agent") String userAgent) {
return "Header 中的数据,User-Agent: " + userAgent;
}
- @RequestHeader("User-Agent") 直接把请求头中 User-Agent 的值绑定到 userAgent 变量。
2.4返回页面(@Controller vs @RestController)
- @Controller:方法返回值会被解析为页面路径,跳转到对应页面。
- 示例:
@Controller
@RequestMapping("/return")
public class ReturnController {
@RequestMapping("/returnPage")
public String returnPage() {
return "index.html"; // 跳转到 static/index.html 页面
}
}
- 方法返回 index.html ,会跳转到 static/index.html 页面(默认请求路径是 index.html/index.htm/index.jsp )。
- @RestController:方法返回值会转成 JSON 或字符串,不会跳转页面。
- 区别: @Controller 配合 @ResponseBody 等于 @RestController 。