[英]Jetty and Jersey 404 error on an old project
As part of my work, I am trying to update some of our services and one is being deployed with Jetty & Jersey.作为我工作的一部分,我正在尝试更新我们的一些服务,其中一项服务正在与 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
.不幸的是,代码很旧(一些依赖项来自 2014 年),并且在编译和服务器启动时,每当我从我的 IDE 中使用
mvn jetty:run
,根目录都会正确显示Directory /
消息,而对于所有其他 URL,我得到错误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.我搜索了很多,但代码似乎是正确的,唯一缺少的是
web.xml
但我认为 Jetty 是嵌入的,我需要提到的是,这段代码已经作为 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: /
http://localhost:8080/v4/restEndpoint/getsamplejson
返回404 NOT FOUND
http://localhost:8080/
显示Directory: /
Should I try to build it as a JAR and run it through that, instead of using the mvn jetty:run
command?我应该尝试将它构建为 JAR 并通过它运行它,而不是使用
mvn jetty:run
命令吗?
You have an embedded-jetty instance, started from code.您有一个从代码开始的嵌入式码头实例。
That is evidenced by the ApiService
source you have provided.您提供的
ApiService
源证明了这ApiService
。
You cannot use the jetty-maven-plugin
to manage / start / run that class.您不能使用
jetty-maven-plugin
来管理/启动/运行该类。
The jetty-maven-plugin
is exclusively for working with webapps, either as WAR packaged files, or as exploded webapp directories. jetty-maven-plugin
专门用于处理 webapps,无论是作为 WAR 打包文件,还是作为扩展的 webapp 目录。 (webapps will either have a WEB-INF/web.xml and / or Servlet annotated classes within it) (webapps 将在其中包含 WEB-INF/web.xml 和/或 Servlet 注释类)
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.您需要使用项目独有的其他方式启动服务器,可能是某种主类或测试用例,最终实例化
ApiService
并在其上调用ApiService
.start()
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.