[英]RestTemplate Interceptor
我目前正在尝试合并一个HandlerInterceptorAdapter
但它没有注册,并且将其与其他答案进行比较很难,因为每个人都在使用不同的东西。 我知道WebMvcConfigureAdapter已被弃用,某些版本控制超出了我对项目范围的控制,请参阅下面的使用规范。
有人可以提供一些关于将拦截器与RestTemplate(不是ClientHttpRequestInterceptor)合并的指导。
主要:
@SpringBootApplication
@EnableRetry
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
ApplicationContext ctx = SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder applicationBuilder) {
return applicationBuilder.sources(Application.class);
}
@Bean
private RestTemplate restTemplate(){
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("redacted", 8080));
SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
simpleClientHttpRequestFactory.setProxy(proxy);
simpleClientHttpRequestFactory.setOutputStreaming(false);
RestTemplate template = new RestTemplate();
template.setErrorHandler(new MyResponseErrorHandler());
return template;
}
}
拦截器:com.example.foo.config.request.interceptor
@Component
public class MyInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("INTERCEPTED");
return super.preHandle(request, response, handler);
}
}
InterceptorConfig:com.example.foo.config.request.interceptor
@Configuration
public class InterceptorConfig extends WebMvcConfigurerAdapter {
@Bean
MyInterceptor myInterceptor() {
return new MyInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
super.addInterceptors(registry);
System.out.println("Adding interceptor");
registry.addInterceptor(myInterceptor());
}
}
“添加拦截器”确实被记录,因此我知道正在扫描配置。 我只是无法获取任何拦截器逻辑来记录。
使用:
HandlerInterceptorAdapter
是一个适用于@Controller
或@RestController
。 不是RestTemplete
的实现。
要将其应用于RestTemplete
,您需要使用ClientHttpRequestInterceptor
。
恩。
@Component
public class CustomInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
// ...
}
}
@Configuation
public class RestTempleteConfig {
// ...
@Autowired
private CustomInterceptor customInterceptor;
@Bean
public RestTemplate restTemplate(){
RestTemplate template = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
template.add(customInterceptor);
return template;
}
}
RestTemplate需要ClientHttpRequestInterceptor
setInterceptors(List<ClientHttpRequestInterceptor> interceptors)
设置此访问者应使用的请求拦截器。
您可以使用Servlet过滤器 “拦截”请求/响应,
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response;
用servlet过滤器实现这个。 这里根本没有春天
但是你必须将RestTemplate改为使用其他框架作为泽西
Jersey提供了一个非常方便的实现,例如名为LoggingFilter的过滤器,它可以帮助记录各种传入和传出流量。
正如@WonChulHeo所指出的,你不能将HandlerInterceptorAdapter
与RestTemplate
一起RestTemplate
。 只有ClientHttpRequestInterceptor
。 目前尚不清楚为什么你需要完全HandlerInterceptorAdapter
- 我们只能看到你正在尝试记录请求拦截的事实。 而ClientHttpRequestInterceptor
绝对能够做到同样甚至更多 - 请查看我的工作示例。
PS您的代码中存在错误 - 您无法对@Bean
方法使用private
访问 - 请检查您的private RestTemplate restTemplate() {
please ...
@Slf4j
@RestController
@SpringBootApplication
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class)
.bannerMode(Banner.Mode.OFF)
.run(args);
}
@GetMapping("/users/{id}")
public User get(@PathVariable int id) {
log.info("[i] Controller: received request GET /users/{}", id);
return new User(id, "John Smith");
}
@Bean
public RestTemplate restTemplate(RestTemplateBuilder templateBuilder) {
ClientHttpRequestFactory requestFactory = new BufferingClientHttpRequestFactory(new SimpleClientHttpRequestFactory());
return templateBuilder
.interceptors((request, bytes, execution) -> {
URI uri = request.getURI();
HttpMethod method = request.getMethod();
log.info("[i] Interceptor: requested {} {}", method, uri);
log.info("[i] Interceptor: request headers {}", request.getHeaders());
ClientHttpRequest delegate = requestFactory.createRequest(uri, method);
request.getHeaders().forEach((header, values) -> delegate.getHeaders().put(header, values));
ClientHttpResponse response = delegate.execute();
log.info("[i] Interceptor: response status: {}", response.getStatusCode().name());
log.info("[i] Interceptor: response headers: {}", response.getHeaders());
String body = StreamUtils.copyToString(response.getBody(), Charset.defaultCharset());
log.info("[i] Interceptor: response body: '{}'", body);
return response;
})
.rootUri("http://localhost:8080")
.build();
}
@Bean
ApplicationRunner run(RestTemplate restTemplate) {
return args -> {
ResponseEntity<User> response = restTemplate.getForEntity("/users/{id}", User.class, 1);
if (response.getStatusCode().is2xxSuccessful()) {
log.info("[i] User: {}", response.getBody());
} else {
log.error("[!] Error: {}", response.getStatusCode());
}
};
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
}
HandlerInterceptorAdapter
用于服务器端(即RestController)在服务器处理HTTP请求时拦截一些重要事件,它与使用什么HTTP客户端(例如RestTemplate
) RestTemplate
。
如果要将RestTemplate
用作HTTP客户端,并希望在发出请求之前拦截请求,并在收到响应之后立即拦截,则必须使用ClientHttpRequestInterceptor
。
我试图以比ClientHttpRequestInterceptor更灵活的方式拦截请求和响应。
从您上面的评论中,您无法处理的实际用例是什么? 我认为ClientHttpRequestInterceptor
已经足够灵活,可以实现任何复杂的逻辑来拦截请求和响应。 由于您的问题没有提供有关如何拦截的任何信息,我只能举一个例子来说明ClientHttpRequestInterceptor
可以提供什么。
要配置RestTemplate以使用拦截器:
RestTemplate rt = new RestTemplate();
List<ClientHttpRequestInterceptor> interceptors= new ArrayList<ClientHttpRequestInterceptor>();
inteceptors.add(new MyClientHttpRequestInterceptor());
ClientHttpRequestInterceptor看起来像:
public class MyClientHttpRequestInterceptor implements ClientHttpRequestInterceptor{
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
//The HTTP request and its body are intercepted here which you can log them or modify them. e.g.
System.out.println("Log the HTTP request header: " + request.getHeaders());
//Modify the HTTP request header....
request.getHeaders().add("foo", "fooValue");
//Throw exception if you do not want to send the HTTP request
//If it is at the end of the interceptor chain , call execution.execute() to confirm sending the HTTP request will return the response in ClientHttpResponse
//Otherwise, it will pass the request to the next interceptor in the chain to process
ClientHttpResponse response= execution.execute(request, body);
//The HTTP response is intercepted here which you can log them or modify them.e.g.
System.out.println("Log the HTTP response header: " + response.getHeaders());
//Modify the HTTP response header
response.getHeaders().add("bar", "barValue");
return response;
}
}
请注意,您还可以配置ClientHttpRequestInterceptor
链,该链允许将一些复杂的请求和响应拦截逻辑拆分为许多ClientHttpRequestInterceptor
和可重用的ClientHttpRequestInterceptor
。 它采用责任链设计模式设计,其API体验与Servlet
Filter#doFilter()
非常相似。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.