springboot集成jersey后发布到tomcat/jetty后,调用接口,报错如下:
测试url:http://localhost:80/test/webapi/account/login
工程jersey配置类
jersey配置类代码:
@Component
@ApplicationPath("/webapi/*")
public class AppResourceConfig extends ResourceConfig {
public AppResourceConfig() {
packages("com.test.rs");
register(MultiPartFeature.class);
}
}
错误原因:springboot加载该配置时,默认以ServletRegistrationBean方式加载,在加载时,会在配置的ApplicationPath后面再加上"/*"作为servlet的urlMapping。
jersey自动将ResourceConfig加载为servlet的代码在org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration类。注册servlet代码:
public ServletRegistrationBean jerseyServletRegistration() {
ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(this.config), new String[]{this.path});
this.addInitParameters(registration);
registration.setName(this.getServletRegistrationName());
registration.setLoadOnStartup(this.jersey.getServlet().getLoadOnStartup());
return registration;
}
处理ApplicationPath源码:
private void resolveApplicationPath() {
if (StringUtils.hasLength(this.jersey.getApplicationPath())) {
this.path = parseApplicationPath(this.jersey.getApplicationPath());
} else {
this.path = findApplicationPath((ApplicationPath)AnnotationUtils.findAnnotation(this.config.getApplication().getClass(), ApplicationPath.class));
}
}
判断注解ApplicationPath配置的参数,生成新的path。
private static String parseApplicationPath(String applicationPath) {
if (!applicationPath.startsWith("/")) {
applicationPath = "/" + applicationPath;
}
return applicationPath.equals("/") ? "/*" : applicationPath + "/*";
}
因此,如果像前面代码所示,配置为"/webapi/*"时,实际servlet对应的urlMapping为"/webapi/*/*",这样调用接口实际的url就需要写成 http://localhost:80/test/webapi/*/account/login才能找到正确的path。
如果需要以开始的url访问接口,即不带*的url,那么jersey的配置类ApplicationPath注解需改为@ApplicationPath("/webapi")。这样用http://localhost:80/test/webapi/account/login调用接口就正常了。
另外:springboot启动servlet代码入口:
org.springframework.boot.web.servlet.ServletRegistrationBean类的onStartup方法:
public void onStartup(ServletContext servletContext) throws ServletException {
Assert.notNull(this.servlet, "Servlet must not be null");
String name = this.getServletName();
if (!this.isEnabled()) {
logger.info("Servlet " + name + " was not registered (disabled)");
} else {
logger.info("Mapping servlet: '" + name + "' to " + this.urlMappings);
Dynamic added = servletContext.addServlet(name, this.servlet);
if (added == null) {
logger.info("Servlet " + name + " was not registered (possibly already registered?)");
} else {
this.configure(added);
}
}
}
本文解决SpringBoot集成Jersey后,在Tomcat/Jetty部署时接口调用404问题。由于默认加载配置时在ApplicationPath后加/*导致路径匹配错误,通过调整配置为@ApplicationPath(/webapi)解决。

2667

被折叠的 条评论
为什么被折叠?



