springboot集成jersey导致404错误

springboot集成jersey后发布到tomcat/jetty后,调用接口,报错如下:

测试url:http://localhost:80/test/webapi/account/login

{
  "timestamp": 1532075910649,
  "status": 404,
  "error": "Not Found",
  "message": "No message available",
  "path": "/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);
        }
    }
}

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值