Spring MVC数据绑定和响应学习笔记
学习视频:12001 数据绑定_哔哩哔哩_bilibili
目录
1.数据绑定
简单数据绑定
默认类型数据绑定
简单数据类型绑定的概念
参数别名的设置
@PathVariable注解的两个常用属性
POJO绑定
自定义类型转换器
xml方式
注解方式
数组绑定
集合绑定
复杂POJO绑定
属性为对象类型的数据绑定
属性为List类型的数据绑定
属性为Map类型的数据绑定
消息转换器—HttpMessageConverter接口
JSON转换器配置和静态资源访问配置
2.页面跳转
返回值为void类型的页面跳转到默认页面
返回值为String类型的页面跳转(不携带数据)
返回值为String类型的页面跳转(携带数据)
返回值为ModelAndView类型的页面跳转
3.数据回写
普通字符串的回写
JSON数据的回写
@ResponseBody注解
1.数据绑定
数据绑定的概念
在程序运行时,Spring MVC接收到客户端的请求后,会根据客户端请求的参数和请求头等数据信息,将参数以特定的方式转换并绑定到处理器的形参中。Spring MVC中将请求消息数据与处理器的形参建立连接的过程就是Spring MVC的数据绑定。
Spring MVC数据绑定的过程图
Spring MVC数据绑定中的信息处理过程
Spring MVC数据绑定中的信息处理过程的步骤描述如下。
(1)Spring MVC将ServletRequest对象传递给DataBinder。
(2)将处理方法的入参对象传递给DataBinder。
(3)DataBinder调用ConversionService组件进行数据类型转换、数据格式化等工作,并将ServletRequest对象中的消息填充到参数对象中。
(4)调用Validator组件对已经绑定了请求消息数据的参数对象进行数据合法性校验。
(5)校验完成后会生成数据绑定结果BindingResult对象,Spring MVC会将BindingResult对象中的内容赋给处理方法的相应参数。
简单数据绑定
默认类型数据绑定
当使用Spring MVC默认支持的数据类型作为处理器的形参类型时,Spring MVC的参数处理适配器会默认识别这些类型并进行赋值。Spring MVC常见的默认类型如下所示。 HttpServletRequest:获取请求信息。
HttpServletResponse:处理响应信息。
HttpSession:获取session中存放的对象。
Model/ModelMap:Model是一个接口,ModelMap是一个类,Model的实现类对象和ModelMap对象都可以设置model数据,model数据会填充到request域。
@Controller
public class UserController {/*** 默认参数类型:* HttpServletRequest:请求* HttpServletResponse:响应* HttpSession:session对象* Model:模型,用于存放页面需要的数据的* @return*/@RequestMapping("/findById")public String findById(HttpServletRequest request,HttpServletResponse response,HttpSession session,Model model){System.out.println(response);System.out.println(session);//向模型中存放数据model.addAttribute("msg","你好");//获取请求中参数String userid=request.getParameter("userid");System.out.println("根据id查询用户信息:"+userid);return "success";}}
<body><h1>hello springMVC!!!</h1>${msg}
</body>
简单数据类型绑定的概念
简单数据类型的绑定,就是指Java中基本类型(如int、double、String等)的数据绑定。在Spring MVC中进行简单类型的数据绑定,只需客户端请求参数的名称和处理器的形参名称一致即可,请求参数会自动映射并匹配到处理器的形参完成数据绑定。
@RequestMapping("/getUsername")public String getUsername(String username){System.out.println("用户名:"+username);return "success";}
这时候没有接收到
参数别名的设置
需要注意的是,有时候客户端请求中参数名称和处理器的形参名称不一致,这就会导致处理器无法正确绑定并接收到客户端请求中的参数。为此,Spring MVC提供了@RequestParam注解来定义参数的别名,完成请求参数名称和处理器的形参名称不一致时的数据绑定。
@RequestParam注解的属性
@RequestMapping("/getUsername")public String getUsername(@RequestParam(value = "name",defaultValue = "it")String username){System.out.println("用户名:"+username);return "success";}
去掉s的时候用户名为默认值 it
@PathVariable注解的两个常用属性
当请求的映射方式是REST风格时,上述对简单类型数据绑定的方式就不适用了。为此,Spring MVC提供了@PathVariable注解,通过 @PathVariable注解可以将URL中占位符参数绑定到处理器的形参中。@PathVariable注解有以下两个常用属性。
value:用于指定URL中占位符名称。
required:是否必须提供占位符,默认值为true。
@PathVariable注解的使用
@RequestMapping("/user/{name}")public String getpPathVariable(@PathVariable("name") String username){System.out.println("路径中的参数:"+username);return "success";}
POJO绑定
POJO数据绑定的概念
POJO类型的数据绑定就是将所有关联的请求参数封装在一个POJO中,然后在方法中直接使用该POJO作为形参来完成数据绑定。
POJO数据绑定的使用场景
在使用简单数据类型绑定时,可以很容易的根据具体需求来定义方法中的形参类型和个数,然而在实际应用中,客户端请求可能会传递多个不同类型的参数数据,如果还使用简单数据类型进行绑定,那么就需要手动编写多个不同类型的参数,这种操作显然比较繁琐。为解决这个问题,可以使用POJO类型进行数据绑定。
public class User {private String username;private String password;@Overridepublic String toString() {return "User{" +"username='" + username + '\'' +", password='" + password + '\'' +'}';}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}
}
<%@ page contentType="text/html;charset=gb2312"%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>注册</title></head>
<body><form action="${pageContext.request.contextPath}/registerUser"method="post">用户名:<input type="text" name="username" /><br />密 码:<input type="password" name="password" /><br /><input type="submit" value="注册"/>
</form></body>
</html>
@RequestMapping("/registerUser")public String registerUser(User user){System.out.println("user信息:"+user);return "success";}
这里的参数name的名字和实体类User的属性名一样。可以直接映射
自定义类型转换器
自定义类型转换器使用场景
Spring MVC默认提供了一些常用的类型转换器,这些类型转换器,可以将客户端提交的参数自动转换为处理器形参类型的数据。然而默认类型转换器并不能将提交的参数转换为所有的类型。此时,就需要开发者自定义类型转换器,来将参数转换为程序所需要的类型。
@RequestMapping("/getBirthday")public String getBirthday(Date birthday){System.out.println("出生日期:"+birthday);return "success";}
类型转换失败,这时候就需要类型转换器
xml方式
Converter接口的使用
public class DateConverter implements Converter<String, Date> {@Overridepublic Date convert(String s) {String dateFormatPattern = "yyyy-MM-dd";SimpleDateFormat sdf = new SimpleDateFormat(dateFormatPattern);Date date = null;try {date = sdf.parse(s);} catch (ParseException e) {e.printStackTrace();System.out.println("请采用正确的格式:"+dateFormatPattern);}return date;}}
@RequestMapping("/getBirthday")public String getBirthday(Date birthday){System.out.println("出生日期:"+birthday);return "success";}
<!--配置格式转换器的工厂--><bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"><property name="converters"><array><bean class="com.it.convert.DateConverter"></bean></array></property></bean><!--注解驱动--><mvc:annotation-driven conversion-service="conversionService"/>
注意:“yyyy-MM-dd”这里的dd后面不要有空格,不然写2021-01-01会得不到正确结果
在上述案例中,日期类型的格式转换是基于XML配置自定义转换器实现的。除了XML方式之外,还可以通过@DateTimeFormat注解来简化日期类型的格式转换。使用@DateTimeFormat注解完成日期类型的格式转换无需自定义转换器,也无需在配置文件中定义转换器工厂或格式化工厂,只需将@DateTimeFormat定义在方法的形参前面或成员变量上方,就可以为当前参数或变量指定类型转换规则。
注解方式
@RequestMapping("/getBirthday")public String getBirthday(@DateTimeFormat(pattern = "yyyy-MM-dd") Date birthday){System.out.println("出生日期:"+birthday);return "success";}
<mvc:annotation-driven></mvc:annotation-driven>
数组绑定
数组绑定的使用场景
在实际开发中,可能会遇到客户端请求需要传递多个同名参数到服务器端的情况,这种情况采用前面的简单数据绑定的方式显然是不合适的。此时,可以使用数组来接收客户端的请求参数,完成数据绑定。
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<html><head><title>提交商品</title></head><body>
<form action="${pageContext.request.contextPath }/getProducts"method="post"><table width="220px" border="1"><tr><td>选择</td><td>商品名称</td></tr><tr><td><input name="proIds" value="1" type="checkbox"></td><td>SSM框架实战</td></tr><tr><td><input name="proIds" value="2" type="checkbox"></td><td>JavaWeb案例</td></tr></table><input type="submit" value="提交商品"/>
</form></body></html>
public class Product {private String proId;private String proName;@Overridepublic String toString() {return "Product{" +"proId='" + proId + '\'' +", proName='" + proName + '\'' +'}';}public String getProId() {return proId;}public void setProId(String proId) {this.proId = proId;}public String getProName() {return proName;}public void setProName(String proName) {this.proName = proName;}
}
@Controller
public class ProductController {@RequestMapping("/getProducts")public String getProducts(String[] proIds){for (String proId : proIds){System.out.println("商品的id为"+proId);}return "success";}
}
注意:String[] 后面的proIds要和input里面的name的值一样
集合绑定
集合中存储简单类型数据时,数据的绑定规则和数组的绑定规则相似,需要请求参数名称与处理器的形参名称保持一致。不同的是,使用集合绑定时,处理器的形参名称需要使用@RequestParam注解标注。
如果getProducts( )方法中不使用@RequestParam注解,Spring MVC默认将List作为对象处理,赋值前先创建List对象,然后将proIds作为List对象的属性进行处理。由于List是接口,无法创建对象,所以会出现无法找到构造方法异常。如果将类型更改为可创建对象的类型,如ArrayList,可以创建ArrayList对象,但ArrayList对象依旧没有proIds属性,因此无法正常绑定,数据为空。此时需要告知Spring MVC的处理器proIds是一组数据, 而不是一个单一数据。通过@RequestParam注解,将参数打包成参数数组或集合后,Spring MVC才能识别该数据格式,并判定形参类型是否为数组或集合,并按数组或集合对象的形式操作数据。
@RequestMapping("/getProducts")public String getProducts(@RequestParam("proIds") List<String> proIds){for (String proId : proIds){System.out.println("商品的id为"+proId);}return "success";}
复杂POJO绑定
属性为对象类型的数据绑定
public class Order {private String orderId;public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}
}
public class User {private String username;private String password;private Order order;public Order getOrder() {return order;}public void setOrder(Order order) {this.order = order;}
@RequestMapping("/findOrderWithUser")public String findUserWithOrder(User user){System.out.println("用户名:"+user.getUsername());System.out.println("订单号:"+user.getOrder().getOrderId());return "success";}
<%@ page language="java" contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>订单信息</title></head><body><formaction="${pageContext.request.contextPath }/findOrderWithUser"method="post">所属用户:<input type="text" name="username" /><br />订单编号:<input type="text" name="order.orderId" /><br /><input type="submit" value="查询" />
</form> </body></html>
属性为List类型的数据绑定
public class User {private String username;private String password;private List<Order> orders;private List<String> address;public List<Order> getOrders() {return orders;}public void setOrders(List<Order> orders) {this.orders = orders;}public List<String> getAddress() {return address;}public void setAddress(List<String> address) {this.address = address;}
public class Order {private String orderId;private String orderName;public String getOrderName() {return orderName;}public void setOrderName(String orderName) {this.orderName = orderName;}public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}
}
@Controller("/showOrders")public class OrderController{@RequestMapping("/showOrders")public String showOrders(User user){List<Order> orders = user.getOrders();List<String> address=user.getAddress();for (int i=0;i<orders.size();i++){Order order = orders.get(i);address.get(i);System.out.println("订单编号:"+order.getOrderId()+" 地址是:"+address);}return "success";}}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html><head><title>订单信息</title></head><body>
<form action="${pageContext.request.contextPath }/showOrders"method="post"><table width="220px" border="1"><tr><td>订单号</td><td>订单名称</td><td>配送地址</td></tr><tr><td><input name="orders[0].orderId" value="1" type="text"></td><td><input name="orders[0].orderName" value="Java基础教程"type="text"></td><td><input name="address" value="北京海淀" type="text"></td></tr></table><input type="submit" value="订单信息"/>
</form> </body></html>
属性为Map类型的数据绑定
public class Order {private String orderId;private HashMap<String,Product>productInfo;public HashMap<String, Product> getProductInfo() {return productInfo;}public void setProductInfo(HashMap<String, Product> productInfo) {this.productInfo = productInfo;}public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}
}
public class Product {private String proId;private String proName;@Overridepublic String toString() {return "Product{" +"proId='" + proId + '\'' +", proName='" + proName + '\'' +'}';}public String getProId() {return proId;}public void setProId(String proId) {this.proId = proId;}public String getProName() {return proName;}public void setProName(String proName) {this.proName = proName;}
}
@RequestMapping("/orderInfo")public String getOrderinfo(Order order){//遍历订单中的商品信息System.out.println("订单的编号:"+order.getOrderId());HashMap<String, Product> productInfo=order.getProductInfo();Set<String> keys=productInfo.keySet();for (String key:keys){Product product=productInfo.get(key);System.out.println("类型:"+key+"商品名称:"+product.getProName());}return "success";}}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<form action="${pageContext.request.contextPath}/orderInfo"method="post"><table border="1"><tr><td colspan="2" >
订单id:<input type="text" name="orderId" value="1"></td></tr>
<tr><td>商品Id</td><td>商品名称</td></tr>
<tr><td><input name="productInfo['生鲜'].proId" value="1"type="text"></td><td><input name="productInfo['生鲜'].proName" value="三文鱼" type="text"></td>
</tr><tr><td><input name="productInfo['酒水'].proId" value="2"type="text"></td><td><input name="productInfo['酒水'].proName" value="红牛" type="text"></td></tr></table>
<input type="submit" value="提交"/>
</form>
消息转换器—HttpMessageConverter接口
客户端不同的请求,HttpServletRequest中数据的MediaType可能会不同,如果想将HttpServletRequest中的数据转换成指定对象,或者将对象转换成指定格式的数据,就需要使用对应的消息转换器来实现。Spring中提供了一个HttpMessageConverter接口作为消息转换器。因为数据的类型有多种,所以Spring中提供了多个HttpMessageConverter接口的实现类,其中MappingJackson2HttpMessageConverter是HttpMessageConverter接口的实现类之一,在处理请求时,可以将请求的JSON报文绑定到处理器的形参对象,在响应请求时,将处理器的返回值转换成JSON报文。
HttpMessageConverter与Converter类型转换器的区别
需要注意的是,HttpMessageConverter消息转换器和之前所学习的Converter类型转换器是有区别的。HttpMessageConverter消息转换器用于将请求消息中的报文数据转换成指定对象,或者将对象转换成指定格式的报文进行响应;Converter类型转换器用于对象之间的类型转换。
由于本次演示的是异步数据提交,需要使用jQuery,所以需要将jQuery文件导入到项目中,以便发送ajax请求。在项目的/webapp文件夹下创建名称为js的文件夹,在js文件夹中导入jQuery文件。
public class Product {private String proId;private String proName;@Overridepublic String toString() {return "Product{" +"proId='" + proId + '\'' +", proName='" + proName + '\'' +'}';}public String getProId() {return proId;}public void setProId(String proId) {this.proId = proId;}public String getProName() {return proName;}public void setProName(String proName) {this.proName = proName;}
}
public class Order {private String orderId;private HashMap<String,Product>productInfo;public HashMap<String, Product> getProductInfo() {return productInfo;}public void setProductInfo(HashMap<String, Product> productInfo) {this.productInfo = productInfo;}public String getOrderId() {return orderId;}public void setOrderId(String orderId) {this.orderId = orderId;}
}
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html><head><title>异步提交商品</title><script type="text/javascript"src="${pageContext.request.contextPath}/js/jquery-3.4.1.min.js"></script></head>
</html>
<form id="products"><table border="1"><tr><th>商品id</th><th>商品名称</th><th>提交</th></tr><tr><td><input name="proId" value="1" id="proId" type="text"></td><td><input name="proName" value="三文鱼" id="proName" type="text"></td><td><input type="button" value="提交单个商品"onclick="sumbmitProduct()"></td></tr><tr><td><input name="proId" value="2" id="proId2" type="text"></td><td><input name="proName" value="红牛" id="proName2" type="text"></td><td><input type="button" value="提交多个商品"onclick="sumbmitProducts()"></td></tr></table></form>
<script type="text/javascript">function sumbmitProduct() {var proId = $("#proId").val();var proName = $("#proName").val();$.ajax({ url: "${pageContext.request.contextPath }/getProduct",type: "post",data: JSON.stringify({proId: proId, proName: proName}),contentType: "application/json;charset=UTF-8",dataType: "json",success: function (response) {alert(response);} }); }function sumbmitProducts() {var pro1={proId:$("#proId").val(),proName:$("#proName").val()}var pro2={proId:$("#proId2").val(),proName:$("#proName2").val()}$.ajax({ url: "${pageContext.request.contextPath }/getProductList",type: "post",data: JSON.stringify([pro1,pro2]),contentType: "application/json;charset=UTF-8",dataType: "json",success: function (response) {alert(response);} }); }
</script>
</script>
<mvc:annotation-driven></mvc:annotation-driven><!-- 配置静态资源的访问--><mvc:resources mapping="/js/**" location="/js/" />
@RequestMapping("/getProduct")public String getProduct(@RequestBody Product product){System.out.println("单个商品:"+product);return "success";}@RequestMapping("/getProductList")public String getProductList(@RequestBody List<Product> productList){System.out.println("多个商品:");productList.forEach(product -> {System.out.println(product);});return "success";}
JSON转换器配置和静态资源访问配置
JSON转换器配置和静态资源访问配置,除了之前讲解的配置方案之外,还可以通过其他方式完成,下面讲解两种配置方式,使用<bean>元素配置JSON转换器和静态资源访问的配置方式。
使用<bean>元素配置JSON转换器
<!-- 使用<bean>元素配置注解方式的处理器映射器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping" />
<!-- 使用<bean>元素配置注解方式的处理器适配器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"><property name="messageConverters"><list><!-- 配置JSON转换器 --><bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/></list></property>
</bean>
静态资源访问的配置方式
使用<mvc:default-servlet-handler>配置静态资源
<mvc:default-servlet-handler />
激活Tomcat默认的Servlet来处理静态资源访问
<servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.js</url-pattern>
</servlet-mapping><servlet-mapping><servlet-name>default</servlet-name><url-pattern>*.css</url-pattern>
</servlet-mapping>
2.页面跳转
返回值为void类型的页面跳转到默认页面
当Spring MVC方法的返回值为void类型,方法执行后会跳转到默认的页面。默认页面的路径由方法映射路径和视图解析器中的前缀、后缀拼接成,拼接格式为“前缀+方法映射路径+后缀”。如果Spring MVC的配置文件中没有配置视图解析器,则会报HTTP Status 500错误。
代码演示
@RequestMapping("/register")public void showPageByVoid(){System.out.println("showPageByVoid running");}
<%@ page contentType="text/html;charset=utf-8" language="java" %>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>注册</title></head>
<body><form action="${pageContext.request.contextPath}/registerUser"method="post">用户名:<input type="text" name="username" /><br />密 码:<input type="password" name="password" /><br /><input type="submit" value="注册"/>
</form></body>
</html>
返回值为String类型的页面跳转(不携带数据)
@RequestMapping("/showPageByString")public String showPageByString(){System.out.println("showPageByString running");return "register";}
注意:void类型默认映射路径名就是视图名称
string返回值默认直接是视图名称
返回值为String类型的页面跳转的转发方式
当方法的返回值为普通的字符串时,Spring MVC在方法执行后会默认以转发的方式响应给客户端。除了这种默认的转发方式,还可以返回指定前缀的字符串,来设定处理器执行后对请求进行转发还是重定向,设定转发和重定向的字符串格式如下所示。
- forward:需要转发到的资源路径
- redirect:需要重定向到的资源路径
@RequestMapping("/showPageByForward")public String showPageByForward() {System.out.println("showPageByForward running");return "forward:order.jsp"; }@RequestMapping("/showPageByRedirect")public String showPageByRedirect() {System.out.println("showPageByRedirect running");return "redirect:http://www.itheima.com"; }
以及把showPageByRedirect复制过去也是可以访问到的
返回值为String类型的页面跳转(携带数据)
@RequestMapping("/showPageByRequest")public String showPageByRequest(HttpServletRequest request) {System.out.println("showPageByRequest running");request.setAttribute("username","request"); return "register";}
<%@ page contentType="text/html;charset=utf-8" language="java" %>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>注册</title></head>
<body><form action="${pageContext.request.contextPath}/registerUser"method="post">用户名:<input type="text" name="username" value="${username}" /><br />密 码:<input type="password" name="password" /><br /><input type="submit" value="注册"/>
</form></body>
</html>
另一种
@RequestMapping("/showPageByModel")public String showPageByModel(Model model) {System.out.println("showPageByRequest running");//传递数据model.addAttribute("username","model");return "register";}
返回值为ModelAndView类型的页面跳转
ModelAndView对象组成部分
使用方法的返回值可以设定跳转的逻辑视图名称,使用Model等对象实现页面跳转时传输数据。除此之外,Spring MVC还提供了兼顾视图和数据的对象ModelAndView,ModelAndView对象包含视图相关内容和模型数据两部分,其中视图相关的内容可以设置逻辑视图的名称,也可以设置具体的View实例;模型数据则会在视图渲染过程中被合并到最终的视图输出。
ModelAndView设置视图和数据模型的方法
ModelAndView方法说明
setViewName()方法和setView()方法都是为ModelAndView对象设置视图的方法,其中前者使用更方便,因此setViewName()方法比较常用。后3个方法都是向ModelAndView对象中添加模型数据的,其中addObject(Object attributeValue)方法添加的attributeValue,默认名称为attributeValue类型全限定名的最后一个单词且首字母小写;addObject(String attributeName, Object attributeValue)方法可以在页面上以${attributeName}方式取出attributeValue。
@RequestMapping("/showModelAndView")public ModelAndView showModelAndView() {ModelAndView modelAndView = new ModelAndView();//数据设置modelAndView.addObject("username","santi");User user = new User(); user.setPassword("password");modelAndView.addObject("user",user);//视图设置modelAndView.setViewName("register");return modelAndView;}
3.数据回写
普通字符串的回写
@Controller
public class DataController {@RequestMapping("/showDataByResponse")public void showDataByResponse(HttpServletResponse response){try {response.getWriter().write("success");} catch (IOException e) {e.printStackTrace();}}}
JSON数据的回写
@RequestMapping("showDataByJSON")public void showDataByJSON(HttpServletResponse response) {try { ObjectMapper om = new ObjectMapper();//创建user对象User user = new User();user.setUsername("santi"); user.setPassword("666");//转换成json字符串String ujson = om.writeValueAsString(user);response.getWriter().print(ujson);} catch (IOException e) {e.printStackTrace();}}
@ResponseBody注解
@ResponseBody注解可以标注在方法和类上,当标注在类上时,表示该类中的所有方法均应用@ResponseBody注解。如果需要当前类中的所有方法均应用@ResponseBody注解,也可以使用@RestController注解。
@ResponseBody注解的2个使用要求
使用@ResponseBody注解,项目至少需要符合2个要求,分别如下所示。
1.项目中有转换JSON相关的依赖。
2.可以配置转换JSON数据的消息类型转换器。
针对上述两个要求,chapter12项目都已经满足,项目的pom.xml文件中引入了Jackson相关的依赖,可以用于转换JSON;Spring MVC的配置文件中配置的<mvc:annotation-driven />元素默认注册了Java数据转JSON数据的消息转换器。
@RequestMapping("/showDataByJSON")@ResponseBodypublic User showDataByJSON() {//创建user对象User user = new User();user.setUsername("santi"); user.setPassword("666");//转换成json字符串return user;}
通过一个案例演示使用@ResponseBody注解回写JSON格式的对象数据和集合数据
@RequestMapping("/getUser")@ResponseBodypublic User getUser(){User user = new User();user.setUsername("abc");user.setPassword("213");return user;}@RequestMapping("/addProducts")@ResponseBodypublic List<Product> addProducts(){List<Product> productList=new ArrayList<>();Product p1=new Product();p1.setProId("p01");p1.setProName("三文鱼");Product p2=new Product();p2.setProId("p02");p2.setProName("茅台");productList.add(p1);productList.add(p2);return productList;}
相关文章:

Spring MVC数据绑定和响应学习笔记
学习视频:12001 数据绑定_哔哩哔哩_bilibili 目录 1.数据绑定 简单数据绑定 默认类型数据绑定 简单数据类型绑定的概念 参数别名的设置 PathVariable注解的两个常用属性 POJO绑定 自定义类型转换器 xml方式 注解方式 数组绑定 集合绑定 复杂POJO绑定 属性为对象类…...

Vulnhub JIS-CTF靶机详解
项目地址 https://www.vulnhub.com/entry/jis-ctf-vulnupload,228/https://www.vulnhub.com/entry/jis-ctf-vulnupload,228/ 修改靶机的网卡 开机时长按shift,进入此页面 选择root模式进入 将只读模式改为读写模式 mount -o remount,rw / 查看本机的网卡名称 …...

FPGA资源评估
FPGA资源评估 文章目录 FPGA资源评估前言一、资源评估1.1 资源有哪些1.2 资源统计 二、 FPGA 的基本结构三、 更为复杂的 FPGA 架构 前言 一、资源评估 大家在项目中一般会要遇到需要资源评估的情况,例如立了新项目,前期需要确定使用什么FPGA片子&…...
REST framework中Views API学习
REST framework提供了一个APIView类,它是Django的View类的子类。 APIView类和一般的View类有以下不同: 被传入到处理方法的请求不会是Django的HttpRequest类的实例,而是REST framework的Request类的实例。处理方法可以返回REST framework的…...
Vue(四)——总结
渐进式JavaScript框架 Vue.js是一套构建用户界面(UI)的渐进式JavaScript框架。 1、库和框架的区别? 库:库是提供给开发者的一个封装好的特定于某一方面的集合(方法和函数),库没有控制权&…...

计算机毕业设计 招生宣传管理系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试
🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点…...

练习题PHP5.6+变长参数 ⇒ usort回调后门 ⇒ 任意代码执行
突破长度限制 使用usort上传后门 usort — 使用用户自定义的比较函数对数组中的值进行排序 paramusort(...$GET); ...为php设置可变长参数 在url地址栏中输入[]test&1[]phpinfo();&2assert 包含了phpiinfo()命令执行 结合usort使用 assert…...

EPLAN关于PLC的输入输出模块绘制
EPLAN关于PLC的输入输出模块绘制 总览图上的PLC绘制原理图上的PLC绘制编辑IO注释显示总览界面IO注释自动关联总览IO地址 总览图上的PLC绘制 右键项目【新建】 页类型选择【总览】,描述可以自由编辑,之后确认即可。 由于我们需要绘制PLC的输入输出&#x…...

【Linux】sersync 实时同步
原理 rsync 是不支持实时同步的,通常我们借助于 inotify 这个软件来实时监控文件变化,一旦inotify 监控到文件变化,则立即调用 rsync 进行同步,推送到 rsync 服务端。 环境准备 步骤1:获取数据包 获取 sersync 的包…...

Unity 资源分享 之 恐龙Ceratosaurus资源模型携 82 个动画来袭
Unity 资源分享 之 恐龙Ceratosaurus资源模型携 82 个动画来袭 一、前言二,资源包内容三、免费获取资源包 一、前言 亲爱的 Unity 开发者和爱好者们,大家好!今天要为大家分享一份超级酷炫的 Unity 资源——恐龙资源模型,而且它还…...

【AI绘画】 学习内容简介
AI绘画-学习内容简介 1. 效果展示 本次测试主要结果展示如下: 卡通手办定制1 卡通手办定制2 艺术写真定制 2. 主要目录 AI 绘画- 文生图,图生图及lora使用(基于diffusers) AI 绘画- 模型转换与快速生图(基于diffus…...

树形结构查找(B树、B+树)
平衡树结构的树高为 O(logn) ,平衡树结构包括两种平衡二叉树结构(分别为 AVL 树和 RBT)以及一种树结构(B-Tree,又称 B 树,它的度大于 2 )。AVL 树和 RBT 适合内部存储的应用,而 B 树…...

网络通信(TCP/UDP协议 三次握手四次挥手 )
三、TCP协议与UDP协议 1、TCP/IP、TCP、 UDP是什么 TCP/IP协议是一个协议簇,里面包括很多协议的, UDP只是其中的一个, 之所以命名为TCP/IP协议, 因为TCP、 IP协议是两个很重要的协议,就用他两命名了,而TCP…...
C# ADO.Net 通用按月建表插入数据
原理是获取原表表结构以及索引动态拼接建表SQL,如果月表存在则不创建,不存在则创建表结构 代码如下 /// <summary>/// 根据指定的表名和时间按月进行建表插入(如果不存在对应的月表)/// </summary>/// <param nam…...

19-ESP32-C3加大固件储存区
1默认编译情况。 2、改flash4M。ESP-IDF Partition Table Editor修改。 3、设置输入Partition Table 改自定义.CSV。保存。 4、查看命令输入Partition Table Editor打开-分区表编辑器UI。按图片增加。 nvs,data,nvs,0x9000,0x6000,, phy_init,data,phy,0xF000,0x1000,, factory…...

【STL】stack/queue 容器适配器 deque
1.stack的介绍和使用 1.1.stack的介绍 1. stack是一种容器适配器,专门用在具有后进先出操作的上下文环境中,其删除只能从容器的一端进行元素的插入与提取操作。 2. stack是作为容器适配器被实现的,容器适配器即是对特定类封装作为其底层的容…...

(回溯) LeetCode 17. 电话号码的组合
原题链接 一. 题目描述 17. 电话号码的字母组合 已解答 中等 相关标签 相关企业 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下(与电话按键相同)。注意 1 不对…...

Ghidra:开源软件逆向工程框架
Ghidra 是一个软件逆向工程 (SRE) 框架 Ghidra 是一种尖端的开源软件逆向工程 (SRE) 框架,是美国国家安全局 (NSA) 研究局的产品。 Ghidra 该框架具有高端软件分析工具,使用户能够分析跨各种平台(包括 Windows、macOS 和 Linux)…...

Spring AI 更新:支持OpenAI的结构化输出,增强对JSON响应的支持
就在昨晚,Spring AI发了个比较重要的更新。由于最近OpenAI推出了结构化输出的功能,可确保 AI 生成的响应严格遵守预定义的 JSON 模式。此功能显着提高了人工智能生成内容在现实应用中的可靠性和可用性。Spring AI 紧随其后,现在也可以对OpenA…...
java.util.ConcurrentModificationException 并发修改异常
目录 异常代码片段 详细说明 解决方案 使用迭代器进行遍历 使用临时集合存储结果 异常代码片段 if (ObjectUtil.isNotEmpty(candidateUsers)) {candidateUsers candidateUsers.stream().filter(Objects::nonNull).distinct().collect(Collectors.toList());for (String …...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
JDK 17 新特性
#JDK 17 新特性 /**************** 文本块 *****************/ python/scala中早就支持,不稀奇 String json “”" { “name”: “Java”, “version”: 17 } “”"; /**************** Switch 语句 -> 表达式 *****************/ 挺好的ÿ…...

多种风格导航菜单 HTML 实现(附源码)
下面我将为您展示 6 种不同风格的导航菜单实现,每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...

七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...