-
Notifications
You must be signed in to change notification settings - Fork 41.2k
Improve documentation of how actuator integrates with both Jersey and Spring MVC #17523
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Actually I went ahead on point 4 and found a way to redirect to SpringMVC, the code is a bit rough and need some more polishing in particular on the configurability, and it is probably not suited when there is many stuff handled by Spring MVC, but when there's just two path handled by Spring MVC's dispatcherServlet, this works quite well. import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import static org.springframework.core.Ordered.HIGHEST_PRECEDENCE;
@Component
@Order(HIGHEST_PRECEDENCE)
public class SpringMvcDispatchingFilter implements Filter {
private ServletContext servletContext;
private Set<String> springMvcPrefixes = Set.of("/actuator", "/doc");
@Override
public void init(FilterConfig filterConfig) {
servletContext = filterConfig.getServletContext();
}
@Override
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain) throws IOException,
ServletException {
if (request.getDispatcherType() == DispatcherType.FORWARD) {
chain.doFilter(request, response);
return;
}
if (request instanceof HttpServletRequest && response instanceof HttpServletResponse) {
doHttpFilter((HttpServletRequest) request,
(HttpServletResponse) response,
chain);
return;
}
chain.doFilter(request, response);
}
private void doHttpFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
if (springMvcPrefixes.stream().anyMatch(request.getRequestURI()::startsWith)) {
servletContext.getNamedDispatcher("dispatcherServlet")
.forward(request, response);
}
chain.doFilter(request, response);
}
} |
By the way, auto forwarding to e.g. requesting // For very general mappings (e.g. "/") we need to check 404 first
Resource resource = getResource(request);
if (resource == null) {
logger.trace("No matching resource found - returning 404");
response.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
} Will find no resource and return 404. If uses a @Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/doc/").setViewName("forward:/doc/index.html");
} Then this code // Obtain a RequestDispatcher for the target resource (typically a JSP).
RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath); Will return the rd.forward(request, response); will fail because there's no jersey resource lie that. The only option currently is to forward in the example servlet above. |
@bric3 Let's keep this issue for documenting how the actuator endpoints behave if both Spring MVC and Jersey are on the classpath. This comment doesn't seem it's related to that documentation issue. |
@mbhave Yes sure! I was commenting on my issue so that others know what this is about and how to work around the "issue". This could be especially important when one want to migrate from Jaxrs (and possibly Jersey) to Spring MVC endpoint, but gradually without doing big-bang changes. |
For reference, I have created a simple project that highlights the issue (via failing tests). This project also provides two mitigation of the issue. One that is based on the solution I provide in the above comment, and one that configures Spring Boot. @wilkinsona Do you thing this spring boot configuration (code) could land in some way in the spring boot repo, of course I should open a new issue / pr if you think so. https://github.com/bric3/jersey-webmvc Currently I'm not quite happy to have to configure manually the url-mappings, but that's ok. |
Thanks for the sample, @bric3. You can get things working without relying on your mitigations by configuring the Jersey auto-configuration to register Jersey as a Filter (rather than as a Servlet) and by configuring it to forward to the rest of the filter chain in the event of it being a 404 from Jersey's perspective. To do this, set property(ServletProperties.FILTER_FORWARD_ON_404, true); With these two changes in place, |
Following a suggestion from @wilkinsona on this #2025 (comment), I'm opening this issue, as I believe there could be some refinement in the documentation and in the code too regarding the exposure of actuator endpoints
Reading this https://docs.spring.io/spring-boot/docs/2.1.6.RELEASE/reference/htmlsingle/#production-ready-customizing-management-server-context-path (Using 2.1.6.RELEASE)
I modified the configuration this way
However actuators keep showing up under
/static
instead of/
curl localhost:8080/static/actuator/healthcheck
=> 200curl localhost:8080/actuator/healthcheck
=> 404So either there's something missing on the documentation or they are some limitations to how actuator integrate when there's both spring mvc and jersey.
Even switching the dispatcher servlet to
/
didn't workFrom my points over there #2025 (comment) I iterated a bit on the refinement in this area.
server.servlet.context-path
has no effect when Spring MVC is also present.When the
spring.mvc.servlet.path: /
there this log:This makes sense as the Jersey app intercepts everything on
/*
This last is actually interesting if one want to migrate one endpoint at a time from one technology to another.
The text was updated successfully, but these errors were encountered: