I had a problem when my filter was run twice when the methods returned CompletionStage. From the documentation for RequestMapping( here ), this is a supported return value.
A CompletionStage (implemented, for example, CompletableFuture), which the application uses to get the return value in a separate stream of its choice, as an alternative to returning the called one.
Since the project was quite complex with lots of parallel code, I created a new simple spring-boot project. This is (only) the controller in it:
@Controller
public class BaseController {
@RequestMapping("/hello")
@ResponseBody
public CompletionStage<String> world() {
return CompletableFuture.supplyAsync(() -> "Hello World");
}
}
And filter:
@WebFilter
@Component
public class GenericLoggingFilter extends GenericFilterBean {
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
System.out.println(httpServletRequest.getMethod() + " " +
httpServletRequest.getRequestURI());
chain.doFilter(request, response);
}
}
When I make a call curl http://localhost:8080/hello, it prints twice GET /helloto the console. When I change the controller method to return String:
@RequestMapping("/hello")
@ResponseBody
public String world() {
return "Hello World";
}
. , Callable, concurrency (, spring Async).
, spring -, , , :
@RequestMapping("/hello")
@ResponseBody
public CompletionStage<String> world() {
return CompletableFuture.supplyAsync(() -> {
System.out.println(RequestContextHolder.currentRequestAttributes());
return "Hello World";
});
}
: IllegalStateException: No thread-bound request found...
, :
@RequestMapping("/hello")
@ResponseBody
public Callable<String> world() {
return () -> {
System.out.println(RequestContextHolder.currentRequestAttributes());
return "Hello World";
};
}
, .
- ,
Callable CompletionStage - , . - , ? ,
CompletionStage, . - , ?