我正在尝试使用web.xml,servlet 3.0和jersey API部署我的应用程序。不幸的是,它不起作用。
这是MyApplication.class:
package com.example;
public class MyApplication extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(MyResource.class);
return s;
}
}
这是MyResource:
@Path("/helloworld")
@Produces(MediaType.TEXT_PLAIN)
public class MyResource {
@GET
public String getHello() {
return "HelloWorld !";
}
}
我的web.xml:
<web-app>
<servlet>
<servlet-name>com.example.MyApplication</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>com.example.MyApplication</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
</web-app>
在客户端,我正在使用此网址: HTTP://本地主机:8080 / [项目] /的WebAPI / HelloWorld的
我有这个错误:
java.lang.NullPointerException
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
java.lang.ClassLoader.loadClass(ClassLoader.java:247)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1629)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:491)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
java.lang.Thread.run(Thread.java:662)
怎么了? :/我正在使用Tomcat 7。
PS:使用servlet 2.x,它可以工作:
<servlet>
<servlet-name>Jersey Web Application</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.example</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Jersey Web Application</servlet-name>
<url-pattern>/webapi/*</url-pattern>
</servlet-mapping>
但我稍后会需要异步模式。
谢谢!
答案 0 :(得分:7)
更新:自从写完这个答案后,我发现了一种避免在Tomcat上使用官方Glassfish Jersey实现的web.xml的方法。查看here了解详情。
如果您正在使用标准的Tomcat安装(或其他一些servlet容器),AFAIK就无法明确告诉它在web.xml
文件*中启动哪些servlet。因为无论如何必须使用web.xml
,让最安静的Web服务工作的最简单方法是忘记完全扩展javax.ws.rs.core.Application
并在那里指定上下文路径。您仍然可以使用标准的jax-rs注释来声明实际的Web服务。
的web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
>
<servlet>
<servlet-name>rest-test</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.domain.mypackage</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name> rest-test</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>
两个值得注意的要点:
您需要在WAR文件中捆绑REST实现,因为servlet容器通常不包含一个。由于Jersey是JAX-RS的参考实现,因此我在上面的servlet-class
元素中使用了它。如果需要,可以将其替换为Apache CXF实现。
init-param
元素告诉Jersey哪些软件包要搜索带有Web服务注释的Java文件。编辑此项以指向您的Web服务。请注意,如果您选择使用apache CXF而不是Jersey,则任何init-param
元素中所需的内容都会有所不同。知道CXF的人请发布他们会发布的内容。
如果您正在使用Maven,只需在jersey-servlet
文件的dependencies
部分中向pom.xml
添加依赖关系:
<dependencies>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.18.2</version>
</dependency>
...
</dependencies>
在此之后,使用Java类中的标准JAX-RS注释直接声明Web服务:
package com.domain.mypackage;
import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.GET;
import javax.ws.rs.MatrixParam;
import javax.ws.rs.Path;
// It's good practice to include a version number in the path so you can have
// multiple versions deployed at once. That way consumers don't need to upgrade
// right away if things are working for them.
@Path("calc/1.0")
public class CalculatorV1_0 {
@GET
@Consumes("text/plain")
@Produces("text/plain")
@Path("addTwoNumbers")
public String add(@MatrixParam("firstNumber") int n1, @MatrixParam("secondNumber") int n2) {
return String.valueOf(n1 + n2);
}
}
这应该是你所需要的。如果您的Tomcat安装在端口8080上本地运行,并且您将WAR文件部署到上下文myContext
,请转到
http://localhost:8080/myContext/rest/calc/1.0/addTwoNumbers;firstNumber=2;secondNumber=3
...应该产生预期的结果(5)。
干杯!
*如果您知道如何在不使用web.xml
的情况下将Jersey servlet添加到Tomcat中的上下文中,有人可以解释一下 - 可能是通过使用上下文或生命周期监听器?
答案 1 :(得分:0)
您需要使用以下代码行
在WEB-INF文件夹下创建web.xml<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<servlet>
<servlet-name>ServletAdaptor</servlet-name>
<servlet-class>
org.glassfish.jersey.servlet.ServletContainer
</servlet-class>
<init-param>
<param-name>jersey.config.server.provider.packages</param-name>
<param-value>package where MyResource resides</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ServletAdaptor</servlet-name>
<url-pattern>/webresources/*</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
</web-app>
现在您可以删除MyApplication类。部署和测试Web服务。它会起作用
答案 2 :(得分:0)
package com.example;
@ApplicationPath("/webapi")
public class MyApplication extends Application {
public Set<Class<?>> getClasses() {
Set<Class<?>> s = new HashSet<Class<?>>();
s.add(MyResource.class);
return s;
}
}
答案 3 :(得分:-1)
访问此链接可能有所帮助: https://jersey.java.net/documentation/latest/deployment.html#deployment.servlet.2
部分:4.7.1。 Servlet 2.x容器
<web-app>
<servlet>
<servlet-name>MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<init-param>
...
</init-param>
</servlet>
...
<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>/myApp/*</url-pattern>
</servlet-mapping>
...
</web-app>