第一种方法,用包装类封装对象
实体类对象
- public class User {
-
- private int id;
- private String userName;
- private String realName;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getUserName() {
- return userName;
- }
-
- public void setUserName(String userName) {
- this.userName = userName;
- }
-
- public String getRealName() {
- return realName;
- }
-
- public void setRealName(String realName) {
- this.realName = realName;
- }
-
- @Override
- public String toString() {
- return "User{" +
- "id=" + id +
- ", userName='" + userName + '\'' +
- ", realName='" + realName + '\'' +
- '}';
- }
- }
-
-
- public class Info {
-
- private int id;
- private String address;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- @Override
- public String toString() {
- return "Info{" +
- "id=" + id +
- ", address='" + address + '\'' +
- '}';
- }
- }
-
- public class RequestParam {
-
- private User user;
-
- private Info info;
-
- public User getUser() {
- return user;
- }
-
- public void setUser(User user) {
- this.user = user;
- }
-
- public Info getInfo() {
- return info;
- }
-
- public void setInfo(Info info) {
- this.info = info;
- }
- }
定义了三个实体 RequestParam里面又封装了User类和Info类
JAVA代码
- @RequestMapping(value = "/show",method = RequestMethod.POST)
- public String show(@RequestBody RequestParam param){
-
- User user = param.getUser();
- Info info = param.getInfo();
-
- return user.toString();
- }
前台代码
$("#ok2").click(function(){ var json = {"user":{"id":9527,"userName":"zcy","realName":"钢铁侠"},"info":{"id":998,"address":"纽约"}}; $.ajax({ url:"http://localhost:8080/more/show", type:"post", cache:false, contentType:"application/json", data:JSON.stringify(json), success:function(data){ alert(data); } }); });
可以成功接收到对象,但是显得没有那么优雅,每次请求数据不同都要另外写一个包装类,显得很麻烦。
第二种方法,用Map对象接收 更加简单粗暴
JAVA代码
- @RequestMapping(value = "/show")
- public String test(@RequestBody Map<String,Object> map){
-
- // 拿到Object之后 再做转换为实体即可 可以用FastJson
- Object user = map.get("user");
- Object info = map.get("info");
-
- return "success";
- }
也不够方便 每个对象还要再做一次转换
第三种方法,使用自定义的HandlerMethodArgumentResolver
自定义注解 加在控制器的参数前作为标记
- @Target(ElementType.PARAMETER)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface JsonObject {
- }
自定义处理类 实现HandlerMethodArgumentResolver接口
- public class JsonObjectArgResolverHandler implements HandlerMethodArgumentResolver {
-
- @Override
- public boolean supportsParameter(MethodParameter methodParameter) {
- return methodParameter.hasParameterAnnotation(JsonObject.class);
- }
-
- @Override
- public Object resolveArgument(MethodParameter methodParameter,
- ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest,
- WebDataBinderFactory webDataBinderFactory) throws Exception {
-
- // 获取Controller中的参数名
- String name = methodParameter.getParameterName();
- // 获取Controller中参数的类型
- Class clazz = methodParameter.getParameterType();
- Object arg = null;
- // 获取该参数实体的所用属性
- Field[] fields = clazz.getDeclaredFields();
- // 实例化
- Object target = clazz.newInstance();
-
- // 创建WebDataBinder对象 反射 遍历fields给属性赋值
- WebDataBinder binder = webDataBinderFactory.createBinder(nativeWebRequest,null,name);
- for (Field field:fields){
- field.setAccessible(true);
- String fieldName = field.getName();
- Class<?> fieldType = field.getType();
- // 在request中 多对象json数据的key被解析为 user[id] user[realName] info[address] 的这种形式
- String value = nativeWebRequest.getParameter(name + "[" + fieldName + "]");
- arg = binder.convertIfNecessary(value,fieldType,methodParameter);
- field.set(target,arg);
- }
-
- return target;
- }
- }
注册自己写的处理类
- @Component
- public class MyWebAppConfig implements WebMvcConfigurer {
-
-
- @Override
- public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
- // 配置自定义接收参数
- WebMvcConfigurer.super.addArgumentResolvers(resolvers);
- resolvers.add(new JsonObjectArgResolverHandler());
- }
- }
Controller
- @RequestMapping(value = "/custom")
- public String custom(@JsonObject User user, @JsonObject Info info){
- System.out.println(user.toString());
- System.out.println(info.toString());
-
- return "success";
- }
前台代码
$("#ok2").click(function(){ var json = {"user":{"id":9527,"userName":"zcy","realName":"钢铁侠"},"info":{"id":998,"address":"纽约"}}; $.ajax({ url:"http://localhost:8080/more/custom", type:"post", cache:false, // 直接传josn对象 这里与上文不同 data:json, success:function(data){ alert(data); } }); });
第三种方式相对比较好 但我有几点还是没明白
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory)这个方法中的 ModelAndViewContainer和webDataBinderFactory 这两个对象的作用,怎样写能够优雅,欢迎大家不吝赐教。
<li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
<use xlink:href="#csdnc-thumbsup"></use>
</svg><span class="name">点赞</span>
<span class="count">2</span>
</a></li>
<li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{"mod":"popu_824"}"><svg class="icon" aria-hidden="true">
<use xlink:href="#icon-csdnc-Collection-G"></use>
</svg><span class="name">收藏</span></a></li>
<li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
<use xlink:href="#icon-csdnc-fenxiang"></use>
</svg>分享</a></li>
<!--打赏开始-->
<!--打赏结束-->
<li class="tool-item tool-more">
<a>
<svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
</a>
<ul class="more-box">
<li class="item"><a class="article-report">文章举报</a></li>
</ul>
</li>
</ul>
</div>
</div>
<div class="person-messagebox">
<div class="left-message"><a href="https://blog.csdn.net/pozhenzi9010">
<img src="https://profile.csdnimg.cn/D/9/E/3_pozhenzi9010" class="avatar_pic" username="pozhenzi9010">
<img src="https://g.csdnimg.cn/static/user-reg-year/1x/8.png" class="user-years">
</a></div>
<div class="middle-message">
<div class="title"><span class="tit"><a href="https://blog.csdn.net/pozhenzi9010" data-report-click="{"mod":"popu_379"}" target="_blank">七夜雪</a></span>
</div>
<div class="text"><span>发布了5 篇原创文章</span> · <span>获赞 4</span> · <span>访问量 1万+</span></div>
</div>
<div class="right-message">
<a href="https://im.csdn.net/im/main.html?userName=pozhenzi9010" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
</a>
<a class="btn btn-sm bt-button personal-watch" data-report-click="{"mod":"popu_379"}">关注</a>
</div>
</div>
</div>
第一种方法,用包装类封装对象
实体类对象
- public class User {
-
- private int id;
- private String userName;
- private String realName;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getUserName() {
- return userName;
- }
-
- public void setUserName(String userName) {
- this.userName = userName;
- }
-
- public String getRealName() {
- return realName;
- }
-
- public void setRealName(String realName) {
- this.realName = realName;
- }
-
- @Override
- public String toString() {
- return "User{" +
- "id=" + id +
- ", userName='" + userName + '\'' +
- ", realName='" + realName + '\'' +
- '}';
- }
- }
-
-
- public class Info {
-
- private int id;
- private String address;
-
- public int getId() {
- return id;
- }
-
- public void setId(int id) {
- this.id = id;
- }
-
- public String getAddress() {
- return address;
- }
-
- public void setAddress(String address) {
- this.address = address;
- }
-
- @Override
- public String toString() {
- return "Info{" +
- "id=" + id +
- ", address='" + address + '\'' +
- '}';
- }
- }
-
- public class RequestParam {
-
- private User user;
-
- private Info info;
-
- public User getUser() {
- return user;
- }
-
- public void setUser(User user) {
- this.user = user;
- }
-
- public Info getInfo() {
- return info;
- }
-
- public void setInfo(Info info) {
- this.info = info;
- }
- }
定义了三个实体 RequestParam里面又封装了User类和Info类
JAVA代码
- @RequestMapping(value = "/show",method = RequestMethod.POST)
- public String show(@RequestBody RequestParam param){
-
- User user = param.getUser();
- Info info = param.getInfo();
-
- return user.toString();
- }
前台代码
$("#ok2").click(function(){ var json = {"user":{"id":9527,"userName":"zcy","realName":"钢铁侠"},"info":{"id":998,"address":"纽约"}}; $.ajax({ url:"http://localhost:8080/more/show", type:"post", cache:false, contentType:"application/json", data:JSON.stringify(json), success:function(data){ alert(data); } }); });
可以成功接收到对象,但是显得没有那么优雅,每次请求数据不同都要另外写一个包装类,显得很麻烦。
第二种方法,用Map对象接收 更加简单粗暴
JAVA代码
- @RequestMapping(value = "/show")
- public String test(@RequestBody Map<String,Object> map){
-
- // 拿到Object之后 再做转换为实体即可 可以用FastJson
- Object user = map.get("user");
- Object info = map.get("info");
-
- return "success";
- }
也不够方便 每个对象还要再做一次转换
第三种方法,使用自定义的HandlerMethodArgumentResolver
自定义注解 加在控制器的参数前作为标记
- @Target(ElementType.PARAMETER)
- @Retention(RetentionPolicy.RUNTIME)
- @Documented
- public @interface JsonObject {
- }
自定义处理类 实现HandlerMethodArgumentResolver接口
- public class JsonObjectArgResolverHandler implements HandlerMethodArgumentResolver {
-
- @Override
- public boolean supportsParameter(MethodParameter methodParameter) {
- return methodParameter.hasParameterAnnotation(JsonObject.class);
- }
-
- @Override
- public Object resolveArgument(MethodParameter methodParameter,
- ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest,
- WebDataBinderFactory webDataBinderFactory) throws Exception {
-
- // 获取Controller中的参数名
- String name = methodParameter.getParameterName();
- // 获取Controller中参数的类型
- Class clazz = methodParameter.getParameterType();
- Object arg = null;
- // 获取该参数实体的所用属性
- Field[] fields = clazz.getDeclaredFields();
- // 实例化
- Object target = clazz.newInstance();
-
- // 创建WebDataBinder对象 反射 遍历fields给属性赋值
- WebDataBinder binder = webDataBinderFactory.createBinder(nativeWebRequest,null,name);
- for (Field field:fields){
- field.setAccessible(true);
- String fieldName = field.getName();
- Class<?> fieldType = field.getType();
- // 在request中 多对象json数据的key被解析为 user[id] user[realName] info[address] 的这种形式
- String value = nativeWebRequest.getParameter(name + "[" + fieldName + "]");
- arg = binder.convertIfNecessary(value,fieldType,methodParameter);
- field.set(target,arg);
- }
-
- return target;
- }
- }
注册自己写的处理类
- @Component
- public class MyWebAppConfig implements WebMvcConfigurer {
-
-
- @Override
- public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
- // 配置自定义接收参数
- WebMvcConfigurer.super.addArgumentResolvers(resolvers);
- resolvers.add(new JsonObjectArgResolverHandler());
- }
- }
Controller
- @RequestMapping(value = "/custom")
- public String custom(@JsonObject User user, @JsonObject Info info){
- System.out.println(user.toString());
- System.out.println(info.toString());
-
- return "success";
- }
前台代码
$("#ok2").click(function(){ var json = {"user":{"id":9527,"userName":"zcy","realName":"钢铁侠"},"info":{"id":998,"address":"纽约"}}; $.ajax({ url:"http://localhost:8080/more/custom", type:"post", cache:false, // 直接传josn对象 这里与上文不同 data:json, success:function(data){ alert(data); } }); });
第三种方式相对比较好 但我有几点还是没明白
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory)这个方法中的 ModelAndViewContainer和webDataBinderFactory 这两个对象的作用,怎样写能够优雅,欢迎大家不吝赐教。
来源:CSDN
作者:小屁孩大帅-杨一凡
链接:https://blog.csdn.net/weixin_41722928/article/details/103630904