这感觉它应该是一件简单的事情,但我仍然是SpringBoot和整个Servlet生态系统的新手,所以它不是很明显。我想要一个类似于HandlerInterceptor的接口,它允许我在控制器中完成后修改请求和响应对象。更好的是装饰映射注释,因此我可以指定哪些控制器需要操作。
我现在正在解决的问题,虽然我预计将来会扩展这个问题,但我有一个加密的标头进入我的应用程序,我想要在控制器中解密,然后在途中再次加密进行。
编辑:为清楚起见。
我有一个休息控制器,例如:
@RestController
public class PojoService {
@GetMapping(value = "/path/to/resource")
public ResponseEntity<SomeClass> getLocationData(
@RequestHeader(value = "EncryptedHeader", required = false) String ecryptedHeaderValue) {
DecryptionObject decryptedHeader = new DecryptionObject(pageHeaderValue);
SomePojo result = getResult();
return decryptedHeader.decorateResponseWithEncryptedHeader(result);
}
}
我希望在每个映射上都没有DecryptionObject,而是在我进入映射之前,我通过一些过滤器或钩子解密头,然后在出路时重新加密头。然后我的代码看起来像:
@RestController
public class PojoService {
@GetMapping(value = "/path/to/resource", decryptHeader="EncryptedHeader")
public ResponseEntity<SomeClass> getLocationData(
@RequestHeader(value = "EncryptedHeader", required = false) String decryptedHeaderValue) {
SomePojo result = getResult();
return result;
}
}
我发现HandlerInterceptor不起作用,因为我无法修改拦截器中的请求或响应。希望澄清这个问题。
答案 0 :(得分:2)
您仍然可以使用HandlerInterceptor。创建实现HandlerInterceptor(或扩展HandlerInterceptorAdapter)的类,然后使用另一个扩展WebMvcConfigurer的类来注册它。
@EnableWebMvc
@Configuration
@ComponentScan
public class MyWebConfig implements WebMvcConfigurer {
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new [...]); //Apply to all controllers
registry.addInterceptor(new [...]).addPathPatterns("path1","path2"); //Apply to specific paths to restrict to some controllers.
}
}
您也可以使用过滤器 - 创建您的Filter类并通过声明类型为FilterRegistrationBean的@Bean
来注册它 - 这也允许您限制某些路径。
更新:您可以使用可以由拦截器request.setAttribute("decryptedHeaderValue",<decrypted>)
设置的请求属性来执行此操作。或者如果您具体使用标头,过滤器将更适合您的目的。创建一个新的包装请求类型,它包装传入的请求并执行您想要的任何操作,并将此包装器传递给链中的下一个过滤器。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
[...]
HttpServletRequestWrapper decryptedRequest = new HttpServletRequestWrapper((HttpServletRequest) request) {
public String getHeader(String name) {
if (name.equals("DecryptedHeader")) {
String encrypted = super.getHeader("EncryptedHeader");
String decrypted = decrypt(encrypted);
return decrypted;
}
return super.getHeader(name); //Default behavior
}
}
chain.doFilter(decryptedRequest, response); //Pass on the custom request down
}
然后任何类下线(其他过滤器,控制器等)都可以调用request.getHeader("DecryptedHeader")
来检索解密的标头。这只是许多类似方法中的一种。您可以在注册时限制此过滤器执行的路径。
对于响应,有一个类似的HttpServletResponseWrapper类,您可以使用它来进行自定义。
答案 1 :(得分:0)
我们可以通过interceptor
中的addingAttribute来实现
httpServletRequest.setAttribute(,);