如何将REST Web服务部署到Heroku?Java服务REST资源访问异常求助
别着急,能正常看到欢迎页说明基础部署链路是通的,问题大概率出在REST资源的配置、路径映射或者依赖上,咱们一步步来捋:
1. 先确认REST资源类的注解配置
先检查你的REST类是不是正确用了JAX-RS的注解,比如:
import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/wr") public class TestResource { @GET @Path("/test") @Produces(MediaType.TEXT_PLAIN) public String getTest() { return "Hello REST!"; } }
这里要注意两个点:
- 类上的
@Path和方法上的@Path组合起来是不是正好对应/wr/test - 有没有漏掉JAX-RS的核心依赖?比如用Jersey的话,要确保
jersey-container-servlet这类依赖已经加到pom.xml/build.gradle里,而且是compile/implementation范围(别设成provided,毕竟webapp-runner是嵌入式Tomcat,得自己带全依赖)
2. 检查Web应用的路径映射配置
如果是用传统web.xml配置,一定要确认JAX-RS的Servlet映射是否正确:
<servlet> <servlet-name>Jersey REST Service</servlet-name> <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class> <init-param> <param-name>jersey.config.server.provider.packages</param-name> <param-value>com.yourpackage.resources</param-value> <!-- 替换成你的REST类所在包 --> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Jersey REST Service</servlet-name> <url-pattern>/api/*</url-pattern> <!-- 这里是坑!如果映射的是/api/*,实际访问路径要加/api前缀,变成/api/wr/test --> </servlet-mapping>
要是想让REST路径直接用根路径访问,可以把url-pattern改成/*,但要注意会不会和静态欢迎页的路径冲突。
如果是用无web.xml的注解方式(比如@ApplicationPath),确认你的Application类配置正确:
import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @ApplicationPath("/") // 指定根路径,这样REST的@Path就能直接生效 public class MyApplication extends Application { }
3. 检查Webapp-Runner的启动参数
有没有在启动webapp-runner的时候指定了上下文路径?比如启动命令是:
java -jar webapp-runner.jar --path /myapp target/*.war
那你的访问路径就得加上/myapp前缀,变成http://localhost:8282/myapp/wr/test。本地测试的时候可以去掉--path参数,用默认根路径启动。
4. 查看日志找线索
本地启动的时候盯着控制台输出,看看有没有JAX-RS初始化的日志,比如Jersey有没有扫描到你的REST资源类?如果日志里完全没看到资源注册的信息,那基本就是依赖或者包扫描配置有问题。
Heroku上可以用heroku logs --tail命令看实时日志,找找有没有404错误日志,或者应用启动时的异常信息,这些细节能帮你快速定位问题。
5. 确认WAR包的结构是否正确
解压你的WAR包,检查下WEB-INF/classes里有没有编译好的REST类文件,WEB-INF/lib里有没有JAX-RS相关的jar包(比如jersey系列的jar)。要是类没编译进去,或者依赖缺失,肯定访问不了。
先从这几点排查,应该能找到问题所在~
内容的提问来源于stack exchange,提问作者Kevin

