当前位置: 首页 > 知识库问答 >
问题:

使用web.xml、Servlet3.0和Jersey部署JAX-RS应用程序

柯英奕
2023-03-14
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>

在客户端,我使用这个url:http://localhost:8080/[projectname]/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)
    <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>

谢了!

共有1个答案

樊杰
2023-03-14

更新:自从写了这个答案后,我发现了一种方法,可以使用官方的Glassfish泽西实现来避免在Tomcat上使用web.xml。详情请看这里。

如果您使用的是标准的Tomcat安装(或其他一些servlet容器),AFAIK,那么您不能避免在web.xml文件*中显式地告诉它要启动什么servlet。因为您必须使用web.xml,所以让restful 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容器通常不包含REST实现。由于Jersey是JAX-RS的参考实现,所以我在上面的servlet-class元素中使用了它。如果需要,可以用Apache CXF实现替换它。

    init-param元素告诉Jersey您要在哪些包中搜索带有web服务注释的Java文件。编辑它以指向您的web服务。请注意,如果您选择使用apache CXF而不是Jersey,那么任何init-param元素中所需的内容都将不同。有人谁知道CXF请张贴他们将是什么。

    如果使用Maven,只需在pom.xml文件的dependencies部分中向jersey-servlet添加一个依赖项:

    <dependencies>
      <dependency>
        <groupId>com.sun.jersey</groupId>
        <artifactId>jersey-servlet</artifactId>
        <version>1.18.2</version>
      </dependency>
      ...
    </dependencies>
    
    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)。

    干杯!

  •  类似资料:
    • 经过谷歌搜索,有人说可能是webshpere服务器已经包含了ASM。因此,我从app.war web-INF/lib中删除了asm.jar。但它仍然存在错误。

    • 问题内容: JAX-RS 1.1规范在第6页上说: 如果不存在Application子类,则必须将添加的servlet命名为: 添加的servlet是什么?可以是任意servlet吗? 如果存在Application子类,并且已经定义了一个servlet,该servlet的servlet初始化参数为: 同样,这里的“ servlet”是什么? 如果存在不由现有Servlet处理的Applicati

    • 我正在使用RAD和WAS7.0.23,并尝试在其中部署jax-rs。但是我在部署描述符(web.xml)中发现了以下错误。 错误404:javax.Servlet.unavailableException:SRVE0200E:Servlet[com.ibm.websphere.jaxrs.server.ibmrestServlet]:找不到所需的类-class java.lang.ClassNot

    • 我从JavaEE 6中读到了这一点。 所以如果没有web.xml,我如何告诉应用程序服务器使用Jersey作为JAX-RS规范的实现呢?

    • 我正在开发一个java脚本客户端应用程序,在服务器端我需要处理CORS,所有我用JAX-RS和Jersey编写的服务。我的代码: 感谢佛普尼

    • 16:24:10,350错误[org.jboss.as.server](DeploymentScanner-Threads-2)JBAS015870:部署“search-rest.war”的部署已回滚,并返回以下失败消息:{“JBAS014671:Failed Services”=>{“jboss.deployment.unit.\”search-rest.war\“.WeldStartServi