Rest 应用程序 (Jersey/JAX-RS) 通过 eclipse 在 glassfish 中运行,但在 tomcat 中部署时不运行

Rest app (Jersey/JAX-RS) runs in glassfish through eclipse but not when deployed in tomcat

我使用 eclipse 和 (Jersey/JAX-RS) 创建了一个网络应用程序。虽然当我从 glassfish 中的 eclipse "run on server" 部署 war 文件时一切正常,我从 maven 安装或从 eclipse "export war file" 生成它部署成功但是当我尝试访问与上述第一个选项相同的剩余资源,它们不可用“404”错误。

这是我的 web.xml 文件:

  <?xml version = "1.0" encoding = "UTF-8"?> 
<web-app xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"  
   xmlns = "http://java.sun.com/xml/ns/javaee"  
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
   id = "WebApp_ID" version = "3.0"> 
   <display-name>Rate it</display-name> 

   <welcome-file-list>
        <welcome-file>login.html</welcome-file>
    </welcome-file-list>

   <listener>
        <listener-class>
             com.rateit.util.MyAppServletContextListener
        </listener-class>
   </listener>

   <servlet> 
      <servlet-name>RateIt login services</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.rateit.login</param-value> 
      </init-param> 
      <init-param>
        <param-name>jersey.config.server.provider.classnames</param-name>
        <param-value>org.glassfish.jersey.media.multipart.MultiPartFeature</param-value>
      </init-param>
   </servlet> 

   <servlet-mapping> 
      <servlet-name>RateIt login services</servlet-name> 
      <url-pattern>/loginServices/*</url-pattern> 
   </servlet-mapping> 
</web-app>

这是我的 pom 文件:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.gamechangerapps</groupId>
  <artifactId>rateit</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>

  <name>rateit Maven Webapp</name>
  <url>http://maven.apache.org</url>

  <dependencies>

    <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
    </dependency>  

    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>javax.ws.rs-api</artifactId>
        <version>2.0.1</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.core</groupId>
         <artifactId>jersey-client</artifactId>
         <version>2.22.2</version>
         <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.5</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.eclipsesource.minimal-json/minimal-json -->
    <dependency>
        <groupId>com.eclipsesource.minimal-json</groupId>
        <artifactId>minimal-json</artifactId>
        <version>0.9.4</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/log4j/log4j -->
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.17</version>
    </dependency>


    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>3.2.2</version>
    </dependency>

    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4</version>
    </dependency>

    <dependency>
        <groupId>org.glassfish.jersey.media</groupId>
        <artifactId>jersey-media-multipart</artifactId>
        <version>2.19</version>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.1.0</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.0</version>
    </dependency>

  </dependencies>

  <build>
    <finalName>rateit</finalName>
    <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-war-plugin</artifactId>
              <configuration>
                  <webXml>WebContent\WEB-INF\web.xml</webXml>
              </configuration>
          </plugin>

          <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
            <configuration>
                <source>1.7</source>
                <target>1.7</target>
            </configuration>
        </plugin>
   </plugins>
  </build>
</project>

这是我的项目结构:

project structure

这是登录服务class

package com.rateit.login;

import java.io.InputStream;
import java.util.List;
import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;
import javax.ws.rs.core.UriBuilder;
import org.apache.log4j.Logger;
import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;
import com.rateit.causecodes.LoginCodes;
import com.rateit.inbox.InboxServices;
import com.rateit.mailing.MailServices;
import com.rateit.property.Building;
import com.rateit.property.PropertyDao;
import com.rateit.rating.RatingQueue;
import com.rateit.util.BaseUriProvider;
import com.rateit.util.FileOperations;
import com.rateit.util.GlobalVariables;
import com.rateit.util.JobIdGenerator; 

@Path("/Welcome") 
public class LoginServices {   
     UserDao userDao = UserDao.getInstance();
     MailServices mailBot = MailServices.getInstance();
     FileOperations fileManager = new FileOperations();
     PropertyDao propDao = PropertyDao.getInstance();
     InboxServices inServ = new InboxServices();
     String baseUri = BaseUriProvider.getStreamInstance().getBaseUri();

     static Logger logger = Logger.getLogger(LoginServices.class);

     @Context
     private ServletContext context;

     /**
     * Service for Login purposes  
     *
     * @FormParam   String user email
     * @FormParam   String user password
     * 
     * @return      LoginCodes  LOGIN_SUCCESFUL/LOGIN_FAILURE_INVALID_EMAIL/LOGIN_FAILURE_INVALID_PASSWORD/LOGIN_FAILURE_GENERIC  
     *                   
     */
     @Path("/login")
     @POST
     @Consumes("application/x-www-form-urlencoded")
     public Response login(@FormParam("email") String e, @FormParam("password") String p) {   
         ResponseBuilder builder = null;

         // get new JobId for this operation
         int jobId = JobIdGenerator.getStreamInstance().getJobId();

         // Create the user object
         User userInput = new User(e,p);

         String loginCheck = LoginCodes.LOGIN_FAILURE_GENERIC.getDescription();  

         User userFromDB = userDao.getUser(userInput.getEmail());
         logger.info("JobID="+jobId+" for user with email  "+userInput.getEmail()+" this user "+userFromDB.getEmail()+" was found in DB");

         // login successful
         if(userInput.getEmail().equals(userFromDB.getEmail()) && userInput.getPassword().equals(userFromDB.getPassword())){
             loginCheck = LoginCodes.LOGIN_SUCCESFUL.getDescription();
             builder = Response.seeOther(UriBuilder.fromUri(baseUri+"/login.html").queryParam("user", userFromDB.getEmail()).queryParam("loginCheck", loginCheck).build());
         }
         // invalid mail
         else if(!userInput.getEmail().equals(userFromDB.getEmail())){
             loginCheck = LoginCodes.LOGIN_FAILURE_INVALID_EMAIL.getDescription();
             builder = Response.seeOther(UriBuilder.fromUri(baseUri+"/login.html").queryParam("loginCheck", loginCheck).build());
         }
         // invalid password
         else if(userInput.getEmail().equals(userFromDB.getEmail()) && !userInput.getPassword().equals(userFromDB.getPassword())){
             loginCheck = LoginCodes.LOGIN_FAILURE_INVALID_PASSWORD.getDescription();
             builder = Response.seeOther(UriBuilder.fromUri(baseUri+"/login.html").queryParam("loginCheck", loginCheck).build());
         }
         // both password and mail invalid
         else{
             builder = Response.seeOther(UriBuilder.fromUri(baseUri+"/login.html").queryParam("loginCheck", loginCheck).build());
         }

         logger.info("JobID="+jobId+" Login attempt for user "+e+" "+loginCheck);

         return builder.build();
     }

问题如下:

下面测试不能打剩下的api

@Test
    public void loginUserSuccessTest() 
    {
        // Create a user and add him to the DB
        User testUser = new User("testuser@rateit.com","1234");
        mockDaoObject.addnewUser(testUser);

        // Create a HTTP request
        Client client = ClientBuilder.newClient();
        //WebTarget target = client.target(baseUri+"/loginServices/Welcome/login");
        WebTarget target = client.target("http://localhost:8080/rateit/loginServices/Welcome/login");
        target.property(ClientProperties.FOLLOW_REDIRECTS, false);
        Builder basicRequest = target.request();  

        // Create a form with the front end parameters
        Form form = new Form();
        form.param("email", testUser.getEmail());
        form.param("password", testUser.getPassword());

        // Send the request and get the response
        Response response = basicRequest.post(Entity.form(form), Response.class);

        // Delete the user
        mockDaoObject.deleteUser(testUser);

        // Check that the response is success
        boolean correctCause = response.getLocation().toString().contains("loginCheck=User+logged+in+successfully");
        boolean correctUser = response.getLocation().toString().contains("user=");

        assertEquals(true, correctCause);
        assertEquals(true, correctUser);
        assertEquals(303, response.getStatus());    
    }

任何建议都会有所帮助

经过一些调查,我发现了这个问题。问题是缺少一些依赖项以及 eclipse 中的配置。 我通过检查 tomcat 中的 logs/localhost.date 日志发现了错误。 在那里我发现了以下异常:

15-Oct-2019 23:04:16.492 INFO [http-nio-8080-exec-42] org.apache.catalina.core.ApplicationContext.log Marking servlet [RateIt login services] as unavailable
15-Oct-2019 23:04:16.493 SEVERE [http-nio-8080-exec-42] org.apache.catalina.core.StandardWrapperValve.invoke Allocate exception for servlet [RateIt login services]
    java.lang.ClassNotFoundException: org.glassfish.jersey.servlet.ServletContainer
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1365)
        at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1188)
        at org.apache.catalina.core.DefaultInstanceManager.loadClass(DefaultInstanceManager.java:540)
        at org.apache.catalina.core.DefaultInstanceManager.loadClassMaybePrivileged(DefaultInstanceManager.java:521)
        at org.apache.catalina.core.DefaultInstanceManager.newInstance(DefaultInstanceManager.java:150)
        at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1042)
        at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:761)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:135)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:526)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
        at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:678)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:861)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1579)
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Unknown Source)

基于这个错误,我通过以下 3 个步骤解决了部署问题:

  1. 我在 pom.xml 文件中添加了以下依赖项

    org.glassfish.jersey.containers 球衣容器 servlet 2.19 org.glassfish.jersey.core 球衣服务器 2.19

    1. 我通过eclipse在WEB-INF/lib文件夹中添加了maven依赖

    MyProject->Properties->Deployment Assembly->Add(Maven Dependencies:source and WEB-INF/lib:Deploy Path

    1. 我通过在 eclipse 中导出而不是通过 maven 任务创建了 war 文件