Spring MVC——获取参数和响应

简介: 本文介绍了如何在Spring框架中通过不同的注解和方法获取URL参数、上传文件、处理cookie和session、以及响应不同类型的数据。具体内容包括使用`@PathVariable`获取URL中的参数,使用`MultipartFile`上传文件,通过`HttpServletRequest`和`@CookieValue`获取cookie,通过`HttpSession`和`@SessionAttribute`获取session,以及如何返回静态页面、HTML代码片段、JSON数据,并设置HTTP状态码和响应头。

1. 获取 URL 中的参数

获取 URL 中的参数是通过 @PathVariable 注解实现的

@RequestMapping("/article/{articleId}")
public String method12(@PathVariable("articleId") String articleId){
    return "接收到参数articleId: " + articleId;
}

@RequestMapping("/article/{articleId}")大括号中的内容就相当于占位符,可以传入任何参数,但是不能不传

多个参数也是可以接受的:

@RequestMapping("/article/{articleId}/{name}")
public String method12(@PathVariable String articleId,@PathVariable String name){
    return "接收到参数articleId: " + articleId + ", name :" + name;
}

前面也提到过,路径中的参数相当于占位符,不能少传,顺序也必须一致

把 required 改为 false 也不行

2. 上传文件

通过 MultipartFile可以获取文件的对象

@RequestMapping("/m12")
public String method13(MultipartFile file){
System.out.println(file.getOriginalFilename());
return "接收到参数file: " + file.getOriginalFilename();
}

通过 Fiddler 抓包可以看到上传的二进制文件

这里的重命名和上面的是不一样的,这里使用的是 @RequestPart注解

3. 获取 cookie 和 session

3.1. cookie 和 session 的介绍

cookie 就相当于这个令牌,当用户首次访问一个网站时,服务器可以在响应中设置 Cookie,并将其发送给客户端浏览器。浏览器会将 Cookie 存储起来。在后续的请求中,浏览器会自动在请求头中携带该网站的 Cookie 信息发送给服务器。服务器通过读取 Cookie 中的数据来识别用户和获取相关状态信息。

Session 是在服务器端用于跟踪用户会话状态的一种机制,当用户首次与服务器建立连接时,服务器会创建一个唯一的 Session ID,并将这个 ID 返回给客户端。客户端通常会将 Session ID 存储在 Cookie 中(也可以通过 URL 重写等方式传递)。在后续的请求中,客户端会携带 Session ID,服务器通过这个 ID 来识别特定的用户会话,并从服务器端的存储中获取相应的 Session 数据。

上面的学生信息中,每一个 session ID 都对应一个 session 对象

例如,用户在进行网上购物时,将商品添加到购物车。服务器会在 Session 中记录购物车的内容。当用户在不同页面浏览或进行结算时,服务器通过 Session ID 找到对应的购物车数据,确保用户的购物操作在整个会话过程中保持一致。

也就是说,第一次没有 session 时会先创建,然后把 session ID 通过 Set-cookie 来给客户端

session 是保存在内存中的,如果重启服务器 session 数据就会消失丢失

cookie 和 session 的区别:

  1. cookie 是客户端保存用户信息的一种机制,session 是服务器端保存用户信息的一种机制
  2. cookie 和 session 之间主要是通过 session ID 关联起来的,session ID 是 cookie 和 session 之间的桥梁
  3. cookie 和session 经常会配合使用,但是不是必须配合,可以用 cookie 来保存一些数据在客户端,不一定是用户身份信息或 session ID,session 中的 session ID 也不一定必须用 cookie 来保存,还可以通过其他来传递,例如通过 URL 来传递

3.2. 获取 cookie

先来使用创建 HttpServletRequest 对象来调用 getCookies() 的方法来获取 cookie,因为 cookie 还可能为 null,所以也需要进行判断

//获取cookie
@RequestMapping("getCookie")
public String getCookie(HttpServletRequest request){
Cookie[] cookies = request.getCookies();
if(cookies != null){
    for (Cookie cookie : cookies) {
        System.out.println(cookie.getName() + ":" + cookie.getValue());
    }
}else{
    System.out.println("cookie为空");
}
return "获取cookie成功";
}

在 postman 中添加两个 cookie 值,然后获取 cookie

调用 getCookies() 方法来获取 cookie 的方式是获取所有的 cookie,如果需要获取指定的 cookie 的话还需要遍历,加入判断

通过 @CookieValue 注解使用可以直接获取指定名称的 cookie

@RequestMapping("getCookie2")
public String getCookie2(@CookieValue("name") String name){
    return "从cookie中获取信息,name:" + name;
}

参数名称和 cookie 名是对应的

3.3. 获取 session

由于 getSession 方法是先从 cookie 中找到 session ID,然后根据 session ID 获取 session,所以可能出现 session 为 null 的情况,设置为 true 就会创建一个空的 session,设置为 false 就不会创建,默认是 true

在获取 session 对象之前先设置好 session

@RequestMapping("/setSession")
public String setSession(HttpServletRequest request){
//获取session对象
HttpSession session = request.getSession();
session.setAttribute("userName","zhangsan");
session.setAttribute("age",18);
return "设置session成功";
}
@RequestMapping("/getSession")
public String getSession(HttpServletRequest request){
//先从cookie中找到session ID,然后根据session ID获取session
HttpSession session = request.getSession(false);
if(session == null){
    return "获取session为null";
}
String userName = (String) session.getAttribute("userName");
return "从session中获取userName: " + userName;
}

浏览器中先访问 getSession 时,由于还没有设置 session,所以此时还获取不到 session 信息,不过由于用的是 getSession() 方法,如果 session 为空时会创建一个 session,

设置之后就可以正常获取了

如果换个浏览器重新获取就又获取不到了

这就是因为处于不同的会话中,会话的 id 是不同的,这也就是相当于不同用户访问时处于不同的 session 中会获取不同的 session ID

也可以直接传入 HttpSession 对象来获取:

@RequestMapping("/getSession2")
public String getSession2(HttpSession session){
String userName = (String) session.getAttribute("userName");
if(userName !=null){
    return "从session中获取userName: " + userName;
}else {
    return "获取session为null";
}
}

还有一种方式获取就是通过 @SessionAttribute 注解来获取

@RequestMapping("/getSession3")
public String getSession3(@SessionAttribute String userName){
    return "从session中获取userName: " + userName;
}

通过这种方式来获取指定 session ,这个 session 是必须要设置好的,如果不存在的话就会直接报错,要求强制绑定,例如上面的 userName 如果找不到就会报错

4. 获取 header

http 的请求头是有很多个键值对的,可以通过创建 HttpServletRequest 对象来调用 getHeader 方法来获取指定的请求头

@RequestMapping("/getHeader")
public String getHeader(HttpServletRequest request){
String User_Agent = request.getHeader("User-Agent");
return "User_Agent: " + User_Agent;
}

还可以通过 @RequestHeader注解来获取

@RequestMapping("/getHeader2")
public String getHeader2(@RequestHeader("User-Agent") String User_Agent){
    return "User_Agent: " + User_Agent;
}

5. 响应

5.1. 返回静态页面

先创建一个 html 页面

如果还按照之前的方式进行返回的话,返回的并不是一个 html 页面

@RequestMapping("/response")
@RestController
public class ResponseController {
    @RequestMapping("/returnHtmlPage")
    public String returnHtmlPage(){
        return "/hello.html";
    }
}

如果把 @RestController 改成 @Controller就可以返回 html 页面

@RequestMapping("/response")
@Controller
public class ResponseController {
    @RequestMapping("/returnHtmlPage")
    public String returnHtmlPage(){
        return "/hello.html";
    }
}

对比这两个注解的实现可以发现,可以理解为@RestController 是在 @Controller的基础上实现的,相差了一个 @ResponseBody

@ResponseBody 表示返回数据,如果使用 @Controller再加上@ResponseBody 就又显示的是数据了

@ResponseBody 既是类注解又是方法注解,如果作用在类上,表示该类的所有方法都返回的是数据,如果作用在方法上,表示该方法返回的是数据,其它的不受影响

此外,由于 @Controller 返回的是页面,所以用到了像之前使用的 @RestController返回数据的代码中,就可能报错

如果把原来的返回值当成页面路径返回后,就找不到这个页面,就会给出 404 的状态码

5.2. 返回 html 代码片段

如果还是用 @Controller的话,由于返回的是页面,就找不到对应的路径,所以需要加上 @ResponseBody直接写上去的 html 代码片段会被自动识别:

@ResponseBody
@RequestMapping("/returnHtml")
public String returnHtml(){
    return "<h1>你好</h1>";
}

5.3. 返回 JSON

JSON 是可以表示对象的,返回对象时就会通过 JSON 方式返回

@ResponseBody
@RequestMapping("/returnJson")
public User returnJson(){
    User user = new User();
    user.setName("zhangsan");
    user.setAge(18);
    return user;
}

这里的返回类型也变为了 JSON

5.4. 设置状态码

状态码可以通过创建 HttpServletResponse 对象调用 setStatus 方法进行设置,例如设置一个 404

@ResponseBody
@RequestMapping("/setStatus")
public User setStatus(HttpServletResponse response){
User user = new User();
user.setName("zhangsan");
user.setAge(18);
response.setStatus(404);
return user;
}

虽然说显示的是 404 状态码,但是还是显示了页面

5.5. 设置 header

@RequestMapping中设置一些参数可以修改指定 header 的一些类型

来修改一下请求类型:

@ResponseBody
@RequestMapping(value = "/setHeader",produces = "application/json")
public String setHeader(){
    return "<h1>你好</h1>";
}

还可以添加一个 Header 信息

@ResponseBody
@RequestMapping(value = "/setHeader2")
public String setHeader2(HttpServletResponse response){
response.setHeader("name","zhangsan");
return "success";
}

相关文章
|
2月前
|
JSON 前端开发 Java
Spring Boot框架中的响应与分层解耦架构
在Spring Boot框架中,响应与分层解耦架构是两个核心概念,它们共同促进了应用程序的高效性、可维护性和可扩展性。
65 3
|
2月前
|
前端开发 Java Spring
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
132 2
|
2月前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
223 2
|
2月前
|
前端开发 Java
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
文章介绍了如何使用SpringBoot创建简单的后端服务器来处理HTTP请求,包括建立连接、编写Controller处理请求,并返回响应给前端或网址。
60 0
学习SpringMVC,建立连接,请求,响应 SpringBoot初学,如何前后端交互(后端版)?最简单的能通过网址访问的后端服务器代码举例
|
3月前
|
Java Spring
spring boot 启动项目参数的设定
spring boot 启动项目参数的设定
|
4月前
|
XML Java 数据库
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
这篇文章是Spring5框架的实战教程,详细介绍了事务的概念、ACID特性、事务操作的场景,并通过实际的银行转账示例,演示了Spring框架中声明式事务管理的实现,包括使用注解和XML配置两种方式,以及如何配置事务参数来控制事务的行为。
Spring5入门到实战------15、事务操作---概念--场景---声明式事务管理---事务参数--注解方式---xml方式
|
4月前
|
Java API 数据格式
Spring Boot API参数读取秘籍大公开!6大神器助你秒变参数处理大师,让你的代码飞起来!
【8月更文挑战第4天】Spring Boot凭借其便捷的开发和配置特性,成为构建微服务的热门选择。高效处理HTTP请求参数至关重要。本文介绍六种核心方法:查询参数利用`@RequestParam`;路径变量采用`@PathVariable`;请求体通过`@RequestBody`自动绑定;表单数据借助`@ModelAttribute`或`@RequestParam`;请求头使用`@RequestHeader`;Cookie则依靠`@CookieValue`。每种方法针对不同场景,灵活运用可提升应用性能与用户体验。
77 9
|
4月前
|
XML 前端开发 Java
Spring MVC接收param参数(直接接收、注解接收、集合接收、实体接收)
Spring MVC提供了灵活多样的参数接收方式,可以满足各种不同场景下的需求。了解并熟练运用这些基本的参数接收技巧,可以使得Web应用的开发更加方便、高效。同时,也是提高代码的可读性和维护性的关键所在。在实际开发过程中,根据具体需求选择最合适的参数接收方式,能够有效提升开发效率和应用性能。
136 3
|
Java Spring
Spring怎么又 bug 了,响应结果居然乱码了?
Spring怎么又 bug 了,响应结果居然乱码了?
149 0
Spring怎么又 bug 了,响应结果居然乱码了?
|
2月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
224 2
下一篇
DataWorks