深入解析:SpringMVC的请求接收与结果响应

news/2025/9/21 17:56:50/文章来源:https://www.cnblogs.com/wzzkaifa/p/19103912

SpringMVC2

  • 接收参数的常用注解
  • 响应数据和结果视图

接收参数的常用注解

  1. RequestParam注解
    作用:把请求中的指定名称的参数传递给控制器中的形参赋值
    属性:
    value:请求参数中的名称,指定请求参数名与方法参数名的映射关系(解决名称不一致的问题);
    required:请求参数中是否必须提供此参数,默认值是true,表示必须提供请求参数,若未传会抛异常,设为false则允许为空;
    defaultValue:如果没有传请求参数,使用该默认值。
package com.qcby.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
@Controller
@RequestMapping("/dept")
public class DeptController
{
/**
* RequestParam注解
*/
@RequestMapping("/save1.do")
public String save(@RequestParam(value = "username", required = false, defaultValue = "abc") String name) {
System.out.println("姓名:" + name);
return "suc";
}
}
  1. RequestBody注解
    作用:将整个请求体的内容作为字符串接收(注意:get方法不可以)
    required属性:表示是否必须有请求体,默认值是true

@requestBody注解常用的使用方式有两种:

  • 将json格式的数据绑定到对应的实体类中
    后端@RequestBody注解对应的类在将HTTP的输入流(含请求体)装配到目标类(即:@RequestBody后面 的类)时,会根据json字符串中的key来匹配对应实体类的属性,如果匹配一致且json中的该key对应的值符合(或可转换为)实体类的对应属性的类型要求时,会调用实体类的setter方法将值赋给该属性;
  • 将json格式的数据按照key值分别赋值在对应的字符串中
    使用method="post"提交时,参数不会拼在 URL 后面,而是被封装到请求体(Request Body)中,格式为 key=value&key=value。
<h3>请求参数绑定(@RequestBody注解方式一)</h3><form action="/dept/save2.do" method="post">姓名:<input type="text" name="sname" /><br/>年龄:<input type="text" name="age" /><br/><input type="submit" value="提交" name="aaa"/><br/>
</form>
<h3>请求参数绑定(@RequestBody注解方式二)</h3><form action="/dept/save3.do" method="post">姓名:<input type="text" name="sname" /><br/>年龄:<input type="text" name="age" /><br/><input type="submit" value="提交" name="aaa"/><br/>
</form>
package com.qcby.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/dept")
public class DeptController
{
/**
* RequestBody注解,绑定到对应的实体类中
*/
@RequestMapping("/save2.do")
public String save2(@RequestBody String body){
System.out.println("请求体内容:"+body);
return "suc";
}
/**
* RequestBody注解,别赋值在对应的字符串中
*/
@RequestMapping("/save3.do")
public String getUser(@RequestBody String sname,@RequestBody String age){
System.out.println(sname);
System.out.println(age);
return "suc";
}
}

打印结果:

在这里插入图片描述

  1. RequestHeader注解
    作用:获取指定请求头的信息
    value属性:请求头的名称

servlet 中获取指定请求头信息的方式:

@Controller
@RequestMapping("/user")
public class UserController
{
/**
* servlet提供的获取请求头信息
*/
@RequestMapping("/save7.do")
public String save7(HttpServletRequest request, HttpServletResponse response) {
System.out.println(request.getParameter("username"));
Enumeration<
String> headerNames = request.getHeaderNames();
while (headerNames.hasMoreElements()) {
String headerName = (String) headerNames.nextElement();
String headerValue = request.getHeader(headerName);
System.out.println(headerName + ": " + headerValue);
}
return "suc";
}
}

request 是 HttpServletRequest 类型的对象,代表客户端发送的 HTTP 请求,Enumeration<String> headerNames = request.getHeaderNames(); 即通过 getHeaderNames() 获取所有 HTTP 请求头名称的枚举对象,while (headerNames.hasMoreElements()) { … } 循环遍历枚举对象,其中 hasMoreElements() 表示判断是否还有未处理的请求头名称,headerNames.nextElement(); 获取下一个请求头的名称,request.getHeader(headerName); 根据名称获取对应的请求头值。

<h3>获取请求头信息(servlet提供)</h3><form action="/user/save7.do" method="post">姓名:<input type="text" name="username" /><br/>年龄:<input type="text" name="age" /><br/><input type="submit" value="提交" /><br/>
</form>

打印结果:

在这里插入图片描述

Spring 框架提供的 @RequestHeader 注解用于获取请求头中指定字段的值

@Controller
@RequestMapping("/user")
public class UserController
{
/**
* @RequestHeader 注解
*/
@RequestMapping("/save8.do")
public String save8(@RequestHeader("cookie") String headerValue) {
System.out.println(headerValue);
return "suc";
}
}

其中参数"cookie"表示获取请求头中名为Cookie的字段,注意是获取整个Cookie请求头的原始字符串

<h3>获取请求头信息(@RequestHeader 注解)</h3><form action="/user/save8.do" method="post">姓名:<input type="text" name="username" /><br/>年龄:<input type="text" name="age" /><br/><input type="submit" value="提交" /><br/>
</form>

打印结果:

在这里插入图片描述

  1. CookieValue注解
    作用:用于从请求携带的Cookie中直接获取指定名称Cookie的值
    value属性:cookie的名称
@Controller
@RequestMapping("/user")
public class UserController
{
/**
* CookieValue注解
*/
@RequestMapping("/save9.do")
public String save9(@CookieValue(value = "JSESSIONID") String cookie){
System.out.println("值:"+cookie);
return "suc";
}
}

@CookieValue 注解会自动从所有Cookie中提取指定名称(value = “JSESSIONID”)的单个Cookie的具体值

<h3>获取请求头cookie信息(@CookieValue 注解)</h3><form action="/user/save9.do" method="post">姓名:<input type="text" name="username" /><br/>年龄:<input type="text" name="age" /><br/><input type="submit" value="提交" /><br/>
</form>

打印结果:

在这里插入图片描述

  1. PathVaribale注解
    作用:获取 URL 路径中的占位符参数(适用于 RESTful 风格的 URL)
    例如:url中有/delete/{id},{id}就是占位符
    value属性:指定url中的占位符名称,若方法参数名与占位符名一致可省略

Restful 风格的 URL:请求路径一样,可以根据不同的请求方式去执行后台的不同方法
@GetMapping:映射 GET 请求,用于查询资源
@PostMapping:映射 POST 请求,用于创建新资源
@PutMapping:映射 PUT 请求,用于全量更新资源
@DeleteMapping:映射 DELETE 请求,用于删除资源
restful风格的URL优点:结构清晰、符合标准、易于理解、扩展方便

在这里插入图片描述

package com.qcby.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
//@RequestMapping("/emp")
public class EmpController
{
/**
* 保存
*/
@RequestMapping(path ="/emp",method = RequestMethod.POST)
public String save(){
System.out.println("保存员工...");
return "suc";
}
/**
* 查询所有
*/
@RequestMapping(path ="/emp", method = RequestMethod.GET)
public String findAll(){
System.out.println("查询员工...");
return "suc";
}
/**
* 查询所有
*/
@RequestMapping(path = "/emp/{id}",method = RequestMethod.GET)
public String findById(@PathVariable(value = "id") Integer id){
System.out.println("通过id查询员工..."+id);
return "suc";
}
}
<h3>Restful风格的URL</h3><form action="/emp" method="post"><input type="submit" value="保存员工"><br/>
</form><form action="/emp" method="get"><input type="submit" value="查询员工"><br/>
</form><form action="/emp/1" method="get"><input type="submit" value="通过id查询员工"><br/>
</form>

打印结果:

在这里插入图片描述

响应数据和结果视图

  1. 返回String
@Controller
@RequestMapping("/redict")
public class ReController
{
/**
* 返回字符串(常用)
*/
@RequestMapping("/save1.do")
public String save1(){
System.out.println("执行了save1...");
return "suc";
}
}
  1. 返回值是void
    如果控制器的方法返回值编写成void,SpringMVC 不会自动进行视图解析或数据处理,默认查找JSP页面没有找到,执行程序报404的异常
    解决方式:可以使用请求转发或者重定向跳转到指定的页面,而非依赖 Spring MVC 的视图解析器自动跳转

需要使用 Servlet 规范中的原生 API 获取请求信息和处理响应,三种常见的响应方式:

  • 通过 HttpServletRequest 的 getRequestDispatcher() 方法实现请求转发,可以访问/WEB-INF目录下的资源,以及可以携带request域中的数据到目标资源;
  • 通过 HttpServletResponse 的 sendRedirect() 方法实现重定向,需要注意的是不能直接访问/WEB-INF目录下的资源,且request域中的数据会丢失;
  • 通过 HttpServletResponse 的输出流直接向客户端输出数据,不经过其他资源跳转。
@Controller
@RequestMapping("/redict")
public class ReController
{
/**
* 返回值是void
*/
@RequestMapping("/save2.do")
public void save2(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("执行了save2...");
//请求转发
request.getRequestDispatcher("/WEB-INF/pages/suc.jsp").forward(request,response);
//重定向, request.getContextPath() 用于获取上下文路径
//response.sendRedirect(request.getContextPath() + "/index.jsp");
// 使用response对象直接向客户端输出响应数据
//response.getWriter().print("hello");
return;
}
}
  1. 返回值是ModelAndView对象
    ModelAndView 是 SpringMVC 提供的一个对象,可同时封装模型数据和视图信息,适合需要在一个对象中同时处理数据和视图的场景
@Controller
@RequestMapping("/redict")
public class ReController
{
/**
* 返回ModelAndView对象
*/
@RequestMapping("/save3.do")
public ModelAndView save3(){
System.out.println("执行了save3...");
// 创建mv对象
ModelAndView mv = new ModelAndView();
// 把一些数据,存储到mv对象中
mv.addObject("msg","用户名或者密码已经存在");
// 设置逻辑视图的名称
mv.setViewName("suc");
// 也支持redirect/forward
// mv.setViewName("redirect:/index.jsp");
return mv;
}
}

补充另一种拆开的方式,返回值是String,视图解析器跳转至对应视图,参数列表中携带model来返回数据内容,代码示例:

@Controller
@RequestMapping("/mtype")
public class MtypeController
{
@RequestMapping("/list")
public String selectpage(MtypeQuery mq, Model model){
Page<
Mtype> page = mtypeService.selectObjectByCondition(mq);
model.addAttribute("page", page);
return "mtype";
}
}
  1. SpringMVC 框架提供的forward请求转发
@Controller
@RequestMapping("/redict")
public class ReController
{
/**
* 返回String
* SpringMVC框架提供的请求转发
*/
@RequestMapping("/save4.do")
public String save4(){
System.out.println("执行了save4...");
return "forward:/WEB-INF/pages/suc.jsp";
}
}
  1. SpringMVC 框架提供的redirect请求转发
@Controller
@RequestMapping("/redict")
public class ReController
{
/**
* 返回String
* SpringMVC框架提供的重定向
*/
@RequestMapping("/save5.do")
public String save5(){
System.out.println("执行了save5...");
return "redirect:save1.do";
// 也可重定向到外部URL但无法访问WEB-INF下的资源
//return "redirect:https://www.baidu.com";
}
}

前端编写

<h3>请求转发与重定向</h3><form action="/redict/save1.do" method="get"><input type="submit" value="执行"><br/>
</form><form action="/redict/save2.do" method="get"><input type="submit" value="执行"><br/>
</form><form action="/redict/save3.do" method="get"><input type="submit" value="执行"><br/>
</form><form action="/redict/save4.do" method="get"><input type="submit" value="执行"><br/>
</form><form action="/redict/save5.do" method="get"><input type="submit" value="执行"><br/>
</form>

打印结果:

在这里插入图片描述

  1. ResponseBody响应json数据(重要)

首先需要导入坐标依赖,引入JSON 序列化依赖

<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.9.0</version>
</dependency>

@ResponseBody的使用本质是 “标记返回值需转为响应体”,ResponseBody响应json数据后台代码编写有三种方式,使得返回值会被序列化为 JSON

第一种方式 @ResponseBody 注解加到返回值前

@Controller
@RequestMapping("/redict")
public class ReController
{
/**
* ResponseBody响应json数据(重要)
* 异步的数据交互
*/
@RequestMapping("/save6.do")
public @ResponseBody User save6(@RequestBody User user){
System.out.println(user);
// 模拟,调用业务层代码
user.setUsername("hello");
user.setAge(100);
// 把user对象转换成json字符串,再响应,response.getWriter().print()
return user;
}
}

第二种方式 @ResponseBody 注解加到方法上

@Controller
@RequestMapping("/redict")
public class ReController
{
// 方法上单独使用@ResponseBody
@RequestMapping("/save7.do")
@ResponseBody // 仅当前方法返回数据(不跳转视图)
public User save7(@RequestBody User user) {
System.out.println(user);
user.setUsername("hello");
user.setAge(100);
return user;
// 返回的User对象会被转换为JSON响应
}
}

第三种方式 @ResponseBody 注解加到类上,即类上使用@RestController,等价于@Controller + @ResponseBody

package com.qcby.controller;
import com.qcby.model.User;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/test")
public class TestController
{
// 方法上无需再添加@ResponseBody
@RequestMapping("/save1.do")
public User save6(@RequestBody User user) {
System.out.println(user);
user.setUsername("hello");
user.setAge(100);
return user;
// 返回的User对象会被转换为JSON响应
}
}

前端jsp代码编写

<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head><title>请求参数绑定</title><%--引入jq,使用阿里云的jQuery CDN(无integrity校验,稳定可靠) --%><script src="https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min.js" type="text/javascript"></script><script>// 页面加载$(function(){// 单击事件$("#btn1").click(function(){// 发送ajax的请求$.ajax({type: "post",url: "/redict/save6.do",contentType:"application/json;charset=UTF-8",data:'{"username":"haha","age":"20"}',dataType: "json",success:function(d){// 编写很多代码alert(d.username+" - "+d.age);}});});$("#btn2").click(function(){// 发送ajax的请求$.ajax({type: "post",url: "/redict/save7.do",contentType:"application/json;charset=UTF-8",data:'{"username":"haha","age":"20"}',dataType: "json",success:function(d){// 编写很多代码alert(d.username+" - "+d.age);}});});$("#btn3").click(function(){// 发送ajax的请求$.ajax({type: "post",url: "/test/save1.do",contentType:"application/json;charset=UTF-8",data:'{"username":"haha","age":"20"}',dataType: "json",success:function(d){// 编写很多代码alert(d.username+" - "+d.age);}});});});</script></head><body><h2>响应数据和结果视图</h2><h3>返回值是String</h3><a href="/redict/save1.do" >返回String</a><br/><h3>返回值是void</h3><a href="/redict/save2.do" >返回void</a><br/><h3>返回值是ModelAndView</h3><a href="/redict/save3.do" >返回ModelAndView</a><br/><h3>请求转发返回值是String</h3>
<a href="/redict/save4.do" >返回值是String</a><br/><h3>重定向返回值是String</h3>
<a href="/redict/save5.do" >返回值是String</a><br/><h3>异步的数据交互方式1</h3>
<input type="button" value="ajax交互" id="btn1"><br/>
<h3>异步的数据交互方式2</h3>
<input type="button" value="ajax交互" id="btn2"><br/>
<h3>异步的数据交互方式3</h3>
<input type="button" value="ajax交互" id="btn3"><br/>
</body>
</html>

需要注意的是 DispatcherServlet 会拦截到所有的资源,导致静态资源也会被拦截到,从而不能被使用,需要配置静态资源不进行拦截,在 springmvc.xml 配置文件添加如下配置:

<!-- 设置静态资源不过滤 --><mvc:resources location="/css/" mapping="/css/**"/> <!-- 样式 --><mvc:resources location="/images/" mapping="/images/**"/> <!-- 图片 --><mvc:resources location="/js/" mapping="/js/**"/> <!-- javascript -->

location元素表示webapp目录下的包下的所有文件,mapping元素表示以/static开头的所有请求路径

响应结果:

在这里插入图片描述

后端打印结果:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/908936.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Element UI框架中自定义input组件的placeholder样式

Element UI是基于Vue.js的组件库,提供了一系列的组件,方便在Vue应用程序中快速使用。对于自定义input组件的placeholder样式,可以通过CSS覆盖默认样式来实现。以下是对Element UI中input组件的placeholder样式自定义…

go语言数组的方法

go语言数组的方法 漫思

【C++】类与结构体的区别

区别 技术上 实际上类与结构体在技术层面除了可见性并没有区别,唯一值得一提的区别就是: class类默认情况下其中的变量、函数都为private私有的。 struct结构体默认情况下则都是public公共的。 用法上 何时使用class…

Linux云端服务器上部署Spring Boot应用

在Linux云服务器上部署Spring Boot应用环境准备:确保Java JDK已安装。Spring Boot通常需要Java 8或更高版本。使用 java -version来确认Java版本。 安装Maven(如果是Maven项目)或Gradle(如果是Gradle项目),这取决…

HTML表单验证:确认input元素输入为具有特定整数和小数位数的数值

为了确保HTML表单中的 input元素接收具有特定整数位和小数位数的数值,您需要利用HTML和JavaScript进行前端验证。在HTML5中,可以使用内建的表单验证功能,比如 pattern属性,然而 pattern属性主要用于字符串的正则表…

课前问题思考3

1.什么样的方法应该用static修饰?不用static修饰的方法往往具有什么特性?Student的getName应该用static修饰吗?什么样的方法应该用static修饰?方法不依赖于类的实例状态。 方法提供的功能与类的实例无关。 工具类方…

实用指南:Docker部署Drawnix开源白板工具

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

go静态方法

go静态方法 漫思

在CentOS上配置SVN至Web目录的自动同步

配置SVN(Subversion)到Web目录的自动同步在CentOS系统中是一种有效的代码部署方法,它可以让团队成员更便捷地管理和发布Web项目。以下是如何在CentOS上实现SVN仓库到Web目录的自动同步的详细步骤。= 1. 安装并配置S…

AIGC在游戏开发中的革命性影响:从生产效率到体验创新 - 详解

AIGC在游戏开发中的革命性影响:从生产效率到体验创新 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Cons…

使用Docker配置并连接HBase的Java API

配置并使用Docker容器化HBase,并通过Java API进行连接,首先涉及到Docker配置HBase环境以及编写Java代码以编程方式连接HBase。以下是这一流程的具体步骤。 使用Docker部署HBase获取HBase镜像:使用Docker Hub提供的官…

在Linux环境下安装和卸载DMETL5数据迁移工具

在Linux环境下,安装和卸载特定的数据迁移工具,如DMETL5,通常涉及到一系列具体步骤。由于DMETL5不是一个广泛认知的公共软件,我们可以遵循一般的Linux软件安装和卸载流程来讨论这个问题。 安装DMETL5数据迁移工具 通…

赛前训练3 欧拉路

以下,斜体表示注意点,粗体表示技巧点。 无向图欧拉路径的判定:除去孤点之外图联通。度数为奇数的点只有 \(0\) 或 \(2\) 个。有向图欧拉路径的判定:除去孤点之外图联通。出度比入度大一或入度比出度大一的有 \(0\)…

HDFS 纠删码技术(Erasure Coding, EC)详解 - 指南

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

SQL小贴式: 用NOT EXISTS 而不是 NOT IN !!!

SQL小贴式: 用NOT EXISTS 而不是 NOT IN !!! 当使用NOT IN进行过滤时, 比如NOT IN xxx 时, 如果 xxx 中有NULL值时, 就会一行也不返回 !在 SQL 中,NOT IN 子查询遇到 NULL 值时会产生意外行为,主要因为 SQL 使用三值…

CF global round 29 CD

CF global round 29 CDCF global round 29 C 思路: 只要考虑每个 0 的位置怎么更新 考虑从当前 pos[i] 转移到下一个 pos[i+1] 的位置 分三种情况, 中间没有 1, 只要当前位置有一个位置左右两种情况都能转移 中间 1…

go语言复杂的map

go语言复杂的map 漫思

手撕大模型|FlashAttention 原理及代码解析

在当今大模型蓬勃发展的时代,训练效率成为了制约模型发展与应用的关键因素。Transformer 架构中的自注意力机制虽强大,但面临着高计算成本与内存消耗的挑战。FlashAttention 应运而生,作为一种高效的注意力计算方法…

react工程化

推荐 https://umijs.org/本文来自博客园,作者:jialiangzai,转载请注明原文链接:https://www.cnblogs.com/zsnhweb/p/19103865

CF700E Cool Slogans 做题记录

CF700E Cool Slogans 做题记录 https://www.luogu.com.cn/problem/CF700E 首先条件可以转化为,\(s_i\) 必须是 \(s_{i-1}\) 的 border,否则 \(s_i\) 可以缩短且不是变劣。 子串是后缀的前缀,所以在后缀上考虑。设 \…