我有一个Spring Boot应用程序。 我更改每个发布请求的请求正文。 是否可以在请求到达控制器之前修改请求主体。 请提供示例。
答案 0 :(得分:5)
另一种选择是将属性添加到 HttpServletRequest 对象。然后,您可以使用 @RequestAttribute 批注在Controller类中读取该属性。
在拦截器中
material-design-icons
在控制器中
@Component
public class SimpleInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws ServletException, IOException {
String parameter = request.getParameter("parameter");
if (parameter == "somevalue") {
request.setAttribute("customAttribute", "value");
}
return true;
}
}
这具有不修改请求正文的优点。
答案 1 :(得分:2)
简短回答
是的,但不容易。
详细信息
我知道三种更改请求内容的选项
“之前”到达控制器中的处理程序方法;
由于您已经在使用spring-boot, 选项3,自定义Spring HandlerInterceptor, 似乎是最适合您的选择。
这是一个指向Baeldung Article的链接,其中涉及弹簧HandlerInterceptor。
Baeldung文章不是您问题的完整答案
因为您一次只能读取InputStrem
返回的HttpServletRequest
。
您将需要创建扩展HttpServletRequest
的包装器类
并在自定义HandlerInterceptor内的包装类中包装每个请求。
包装器类
HttpServletRequest
InputStream ByteArrayOutputStream
。toByteArray
从流中检索实际的byte[]
。getInputStream
方法。byte[]
时,将getInputStream
包装在ByteArrayInputStream中。返回此流。答案 2 :(得分:0)
我的回答使用 HTTP过滤器。
RequestFilter.java
@Component
public class RequestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
RequestWrapper wrappedRequest = new RequestWrapper((HttpServletRequest) request);
chain.doFilter(wrappedRequest, response);
}
@Override
public void destroy() {
}
}
RequestWrapper.java
public class RequestWrapper extends HttpServletRequestWrapper {
private final String body;
private ObjectMapper objectMapper = new ObjectMapper();
public RequestWrapper(HttpServletRequest request) throws IOException {
// So that other request method behave just like before
super(request);
StringBuilder stringBuilder = new StringBuilder();
BufferedReader bufferedReader = null;
try {
InputStream inputStream = request.getInputStream();
if (inputStream != null) {
bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
char[] charBuffer = new char[128];
int bytesRead = -1;
while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
stringBuilder.append(charBuffer, 0, bytesRead);
}
} else {
stringBuilder.append("");
}
} catch (IOException ex) {
throw ex;
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException ex) {
throw ex;
}
}
}
// Store request body content in 'requestBody' variable
String requestBody = stringBuilder.toString();
JsonNode jsonNode = objectMapper.readTree(requestBody);
//TODO -- Update your request body here
//Sample
((ObjectNode) jsonNode).remove("key");
// Finally store updated request body content in 'body' variable
body = jsonNode.toString();
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes());
ServletInputStream servletInputStream = new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return false;
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setReadListener(ReadListener listener) {
}
};
return servletInputStream;
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
}
答案 3 :(得分:0)
一种解决方法是反思。 ProceedingJoinPoint包含传递给方法的args对象
@Aspect
@Component
public class AopInterceptor {
@Around(value = "@annotation(xyz.rpolnx.spring.web.poc.annotation.AopIntercepExample)")
public Object handler(final ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
Object[] args = joinPoint.getArgs();
Class<?> someClass = args[0].getClass();
Field field = someClass.getDeclaredField("custom");
field.setAccessible(true);
field.set(args[0], "custom");
field.setAccessible(false);
return joinPoint.proceed();
}
}
@RestController
public class SimpleController {
@PostMapping("/aop")
@AopIntercepExample
public Person handleAopIntercept(@RequestBody Person nodes) {
return nodes;
}
}
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface AopIntercepExample {
}
public class Person {
private String name;
private String id;
private String custom;
}
答案 4 :(得分:-1)
这是我使用RequestBodyAdvice实现它的方式:
@ControllerAdvice
public class CustomRequestBodyAdvice implements RequestBodyAdvice {
a。支持:在这里,您可以通过指定请求主体的类型来控制要定位的控制器,更好地控制哪个请求主体
@Override
public boolean supports(MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
log.info("In supports() method of {}", getClass().getSimpleName());
return methodParameter.getContainingClass() == AuthorController.class && type.getTypeName() == AuthorDTO.class.getTypeName();
}
b。 beforeBodyReady
<!-- language: lang-js -->
@Override
public HttpInputMessage beforeBodyRead(HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
log.info("In beforeBodyRead() method of {}", getClass().getSimpleName());
return httpInputMessage;
}
c。 afterBodyRead:在这里您可以修改请求正文
<!-- language: lang-js -->
@Override
public Object afterBodyRead(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
log.info("In afterBodyRead() method of {}", getClass().getSimpleName());
if (body instanceof AuthorDTO) {
AuthorDTO authorDTO = (AuthorDTO) body;
authorDTO.setName("Test");
return authorDTO;
}
return body;
}
d。 handleEmptyBody
<!-- language: lang-js -->
@Override
public Object handleEmptyBody(Object body, HttpInputMessage httpInputMessage, MethodParameter methodParameter, Type type, Class<? extends HttpMessageConverter<?>> aClass) {
log.info("In handleEmptyBody() method of {}", getClass().getSimpleName());
return body;
}
来源:http://www.javabyexamples.com/quick-guide-to-requestbodyadvice-in-spring-mvc