第一种方法,用包装类封装对象
实体类对象
-
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:void(0)'>
第一种方法,用包装类封装对象
实体类对象
-
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:void(0)'>