Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法

简介: Spring拦截器获取request请求体中的json数据,并转换成Java对象的解决办法

1、要被拦截的Controller接口


我们需要一个更新用户信息接口,请求方式为POST,参数类型为对象类型(UserInfo),代码如下:

@ResourceprivateUserServiceuserService;
/*** 更新用户信息** @param request* @param userInfo* @return*/@RequestMapping(value="/updateUserInfo", produces="application/json;charset=UTF-8",
method=RequestMethod.POST)
publicJSONObjectupdateUserInfo(HttpServletRequestrequest, @RequestBodyUserInfouserInfo) {
   ...
userService.updateUserInfo(userInfo);  
    ...
}


2、拦截器


我们要在拦截器中拦截该接口,并获取其请求参数UserInfo对象。


如果只是获取普通的请求对象(eg:用户ID -> userId),我们可以直接在拦截器中,通过如下代码即可获取request请求体中的参数数据:

@OverridepublicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecto) {
   ......
// user ID为string类型,所以可以直接拿到数据,// 但是如果参数是对象类型/JSON类型数据,则无法通过这种方式获取!StringuserId=request.getParameter("userId");
   .....
}


3、HttpServletRequestWrapper解决这一问题


在拦截器中写一个内部类 RequestWrapper ,让其继承 HttpServletRequestWrapper:

classRequestWrapperextendsHttpServletRequestWrapper {

RequestWrapper 重写父类方法,最终完整的拦截器代码如下:


/*** 拦截器: ** @author csp* @date 2022-01-06 15:36:41*/publicclassUserInterceptorimplementsHandlerInterceptor {
privatefinalstaticLoggerlogger=LoggerFactory.getLogger(UserInterceptor.class);
@ResourceprivateUserServiceuserService;
/*** 前置拦截** @param request* @param response* @param o* @return* @throws Exception*/@OverridepublicbooleanpreHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecto) throwsException {
// 从request请求体中拿到body中的JSON对象参数RequestWrapperrequestWrapper=newRequestWrapper(request);
StringjsonBody=requestWrapper.getBody();
UserInfouserInfo=JSONObject.toJavaObject(JSONObject.parseObject(jsonBody), UserInfo.class);
// 根据userInfo校验是否具备权限BooleanisAuth=userService.getAuthByUserInfo(userInfo);
if (!isAuth) {
// response响应给浏览器无权限,代码略           ...
returnfalse;
        }
returntrue;
    }
@OverridepublicvoidpostHandle(HttpServletRequestrequest, HttpServletResponseresponse, Objecto, ModelAndViewmodelAndView) throwsException {}
@OverridepublicvoidafterCompletion(HttpServletRequestrequest, HttpServletResponseresponse, Objecto, Exceptione) throwsException {}
// RequestWrapper 内部类classRequestWrapperextendsHttpServletRequestWrapper {
privatefinalStringbody;
publicRequestWrapper(HttpServletRequestrequest) {
super(request);
StringBuilderstringBuilder=newStringBuilder();
BufferedReaderbufferedReader=null;
InputStreaminputStream=null;
try {
inputStream=request.getInputStream();
if (inputStream!=null) {
bufferedReader=newBufferedReader(newInputStreamReader(inputStream));
char[] charBuffer=newchar[128];
intbytesRead=-1;
while ((bytesRead=bufferedReader.read(charBuffer)) >0) {
stringBuilder.append(charBuffer, 0, bytesRead);
                    }
                } else {
stringBuilder.append("");
                }
            } catch (IOExceptionex) {
            } finally {
if (inputStream!=null) {
try {
inputStream.close();
                    } catch (IOExceptione) {
e.printStackTrace();
                    }
                }
if (bufferedReader!=null) {
try {
bufferedReader.close();
                    } catch (IOExceptione) {
e.printStackTrace();
                    }
                }
            }
body=stringBuilder.toString();
        }
@OverridepublicServletInputStreamgetInputStream() throwsIOException {
finalByteArrayInputStreambyteArrayInputStream=newByteArrayInputStream(body.getBytes());
ServletInputStreamservletInputStream=newServletInputStream() {
@OverridepublicbooleanisFinished() {
returnfalse;
                }
@OverridepublicbooleanisReady() {
returnfalse;
                }
@OverridepublicvoidsetReadListener(ReadListenerreadListener) {
                }
@Overridepublicintread() throwsIOException {
returnbyteArrayInputStream.read();
                }
            };
returnservletInputStream;
        }
@OverridepublicBufferedReadergetReader() throwsIOException {
returnnewBufferedReader(newInputStreamReader(this.getInputStream()));
        }
publicStringgetBody() {
returnthis.body;
        }
    }
}

这样,就可以在拦截器中,拦截request请求,并获取request请求体中的json/对象类型的参数啦!

相关文章
|
2月前
|
缓存 安全 Java
Spring Get请求 与post请求
本文详细介绍了Spring框架中GET请求和POST请求的区别及应用场景。GET请求用于从服务器获取资源,参数附在URL末尾,适合查看非敏感信息;POST请求用于向服务器提交数据,参数在请求体中传输,适合处理敏感信息。Spring通过`@GetMapping`和`@PostMapping`注解分别处理这两种请求。此外,文章还提供了示例代码,展示了如何在Spring中实现这两种请求的处理。最后,文章总结了推荐使用POST请求的原因,包括更高的安全性、更大的数据传输量、更好的幂等性及灵活性。
Spring Get请求 与post请求
|
19天前
|
设计模式 前端开发 Java
Spring MVC——项目创建和建立请求连接
MVC是一种软件架构设计模式,将应用分为模型、视图和控制器三部分。Spring MVC是基于MVC模式的Web框架,通过`@RequestMapping`等注解实现URL路由映射,支持GET和POST请求,并可传递参数。创建Spring MVC项目与Spring Boot类似,使用`@RestController`注解标记控制器类。
30 1
Spring MVC——项目创建和建立请求连接
|
9天前
|
前端开发 Java 测试技术
深入剖析:Spring Boot Controller中请求处理方法的访问修饰符
【10月更文挑战第21天】 在Spring Boot应用中,Controller类中的请求处理方法通常用于处理HTTP请求。这些方法的访问修饰符(private或public)对方法的行为和可访问性有着重要影响。本文将深入探讨在Controller中使用private和public修饰符的区别,以及它们对Spring MVC框架的影响。
17 8
|
27天前
|
存储 Java API
如何使用 Java 记录简化 Spring Data 中的数据实体
如何使用 Java 记录简化 Spring Data 中的数据实体
33 9
|
22天前
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
17 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
29天前
|
前端开发 Java Spring
【Spring】“请求“ 之后端传参重命名,传递数组、集合,@PathVariable,@RequestPart
【Spring】“请求“ 之后端传参重命名,传递数组、集合,@PathVariable,@RequestPart
23 2
|
29天前
|
JSON 前端开发 Java
【Spring】“请求“ 之传递 JSON 数据
【Spring】“请求“ 之传递 JSON 数据
82 2
|
29天前
|
前端开发 Java Spring
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
【Spring】“请求“ 之传递单个参数、传递多个参数和传递对象
95 2
|
29天前
|
XML Java 应用服务中间件
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
【Spring】运行Spring Boot项目,请求响应流程分析以及404和500报错
136 2
|
3月前
|
安全 Java 应用服务中间件
如何在 Spring Boot 3.3 中实现请求 IP 白名单拦截功能
【8月更文挑战第30天】在构建Web应用时,确保应用的安全性是至关重要的。其中,对访问者的IP地址进行限制是一种常见的安全措施,特别是通过实施IP白名单策略,可以只允许特定的IP地址或IP段访问应用,从而有效防止未授权的访问。在Spring Boot 3.3中,我们可以通过多种方式实现这一功能,下面将详细介绍几种实用的方法。
206 1