Jetty和Jersey在一个旧项目中出现404错误。

huangapple go评论74阅读模式
英文:

Jetty and Jersey 404 error on an old project

问题

以下是翻译好的内容:

作为我的工作的一部分,我正在尝试更新一些我们的服务,其中一个服务使用Jetty和Jersey进行部署。不幸的是,这段代码非常老旧(一些依赖来自于2014年),虽然它能够编译并且服务器能够启动,但是每当我在我的IDE中使用mvn jetty:run命令运行它时,根目录显示Directory /消息,但对于其他所有URL,我都会得到404 NOT FOUND错误。

我在控制台上没有收到任何警告/错误消息,也找不到为什么会发生这种情况。我已经进行了大量搜索,但代码似乎是正确的,唯一缺少的是web.xml文件,但我认为Jetty是嵌入式的。需要注意的是,这段代码已经作为一个JAR文件在生产环境中运行。

以下是一些文件内容:

pom.xml
(POM文件内容)

下面的类被引用以启动服务器:
ApiService.java
(ApiService.java的代码内容)

restEndpoint.java
(restEndpoint.java的代码内容)

有任何想法为什么会发生这种情况吗?
http://localhost:8080/v4/restEndpoint/getsamplejson返回404 NOT FOUND
http://localhost:8080/显示Directory: /

我应该尝试将其构建为JAR文件,并通过该方式运行,而不是使用mvn jetty:run命令吗?

英文:

As part of my work, I am trying to update some of our services and one is being deployed with Jetty & Jersey. Unfortunately the code is very old (some dependencies are from 2014), and while it is compiling and server starts, whenever I run it from my IDE with mvn jetty:run the root directory shows the Directory / message correctly whereas for all other URLs I get the error 404 NOT FOUND.

I don't get any warning/error messages on console and I can't find why it happens. I've searched a lot but the code seems correct, the only thing that is missing is the web.xml but I think Jetty is embedded, and I need to mention that this code is already running in production as a JAR.

Below you can see some of the files:

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sample</groupId>
    <artifactId>sample</artifactId>
    <version>2.0</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.2.2.v20140723</version>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>

        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>9.2.3.v20140905</version>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>9.2.3.v20140905</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>2.7</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet-core</artifactId>
            <version>2.7</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-jetty-http</artifactId>
            <version>2.7</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.7</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>2.7</version>
        </dependency>

        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20160212</version>
        </dependency>

    </dependencies>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

</project>

The class below is referenced to start the server:
ApiService.java


import com.simple.api.restendpoint.*;
import org.apache.log4j.Logger;
import org.eclipse.jetty.http.HttpVersion;
import org.eclipse.jetty.server.*;
import org.eclipse.jetty.server.handler.IPAccessHandler;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.servlet.ServletContainer;

import java.util.HashSet;
import java.util.Set;


public class ApiService {
	Logger log = Logger.getLogger(ApiService.class);
	
	private static ApiService instance;
	private final Server server;

	private ApiService(){
		//CREATE CONFIG
		Set<Class<?>> s = new HashSet<>();
		s.add(restEndpoint.class);		

		ResourceConfig config = new ResourceConfig(s);

		//CREATE CONTAINER
		ServletContainer container = new ServletContainer(config);

		//CREATE CONTEXT
		ServletContextHandler context = new ServletContextHandler();
		context.setContextPath("/");
		context.addServlet(new ServletHolder(container),"/*");

		//CREATE RPC SERVER
		QueuedThreadPool threadPool = new QueuedThreadPool();
        threadPool.setMaxThreads(50);
		server = new Server(threadPool);

		server.setHandler(context);

		ServerConnector connector = new ServerConnector(server);
		connector.setPort(8080);

		server.addConnector(connector);

        SslContextFactory sslContextFactory = new SslContextFactory();
        sslContextFactory.setKeyStorePath("testkeystore");
        sslContextFactory.setKeyStorePassword("testkeystore");
        sslContextFactory.setKeyManagerPassword("testkeystore");

        // SSL HTTP Configuration
        HttpConfiguration https_config = new HttpConfiguration();
        https_config.addCustomizer(new SecureRequestCustomizer());

        // SSL Connector
        ServerConnector sslConnector = new ServerConnector(server,
            new SslConnectionFactory(sslContextFactory,HttpVersion.HTTP_1_1.asString()),
            new HttpConnectionFactory(https_config));
        sslConnector.setPort(Settings.getInstance().getRpcPort());
        server.addConnector(sslConnector);
        
	}

	public static ApiService getInstance() {
		if (instance==null) {
			instance = new ApiService();
		}
		return instance;
	}

	public void start() {
		try {
        	//START RPC 
			server.start();
			server.join();
			log.info("Server started");
		}
        catch (Exception e) {
        	//FAILED TO START RPC
			log.error("Error starting server");
		} finally {
			server.destroy();
		}
	}
}

restEndpoint.java

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.container.AsyncResponse;
import javax.ws.rs.container.Suspended;
import javax.ws.rs.core.Context;
import org.apache.log4j.Logger;
import org.json.JSONArray;
import org.json.JSONObject;

@Path("/v4/restEndpoint")
@Produces({"application/json"})
public class restEndpoint {
    Logger log = Logger.getLogger(restEndpoint.class);

    private static final String VERSION = "v4";

    private static final ExecutorService executors = Executors.newFixedThreadPool(20);

    @Context
    HttpServletRequest request;

    @GET
    @Path("/getsamplejson")
    public void getSampleJson(@Suspended final AsyncResponse asyncResponse) {
        executors.execute(new Runnable() {
            @Override
            public void run() {
                String result = veryExpensiveOperation();
                asyncResponse.resume(result);
            }

            private String veryExpensiveOperation() {
                JSONObject sampleJson = new JSONObject().put("test", 0);
                return sampleJson.toString();
            }
        });
    }
}

Any idea why is it happening?
http://localhost:8080/v4/restEndpoint/getsamplejson returns 404 NOT FOUND
http://localhost:8080/ shows Directory: /

Should I try to build it as a JAR and run it through that, instead of using the mvn jetty:run command?

答案1

得分: 2

你有一个从代码中启动的嵌入式Jetty实例。

这可以从您提供的ApiService源代码中看出。

您不能使用jetty-maven-plugin来管理/启动/运行该类。

jetty-maven-plugin专门用于处理Web应用,可以是打包为WAR文件,也可以是作为已解压的Web应用目录。(Web应用通常会包含WEB-INF/web.xml文件和/或带有Servlet注解的类)

您需要使用其他方法启动服务器,这对于您的项目是独特的,可能是某种主类或测试用例,最终会实例化ApiService并在其上调用.start()方法。

英文:

You have an embedded-jetty instance, started from code.

That is evidenced by the ApiService source you have provided.

You cannot use the jetty-maven-plugin to manage / start / run that class.

The jetty-maven-plugin is exclusively for working with webapps, either as WAR packaged files, or as exploded webapp directories. (webapps will either have a WEB-INF/web.xml and / or Servlet annotated classes within it)

You'll need to start the server using other means that is unique to your project, likely some kind of main class, or testcase, that eventually instantiates the ApiService and calls .start() on it.

huangapple
  • 本文由 发表于 2020年8月26日 01:10:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/63583915.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定