Java 运行Jersey Rest API而不使用容器作为jar
目前,我使用Tomcat将我的后端与RESTAPI一起保存。当我想使用我的前端时,我只是启动Tomcat,它保存后端项目,然后,我可以使用http请求通过RESTAPI访问后端。 现在我考虑摆脱Tomcat,将其部署为jar文件,而不是war文件,并通过Main方法在本地运行它。 我是这样做的(): 我的Rest课程摘录如下:Java 运行Jersey Rest API而不使用容器作为jar,java,rest,jersey,Java,Rest,Jersey,目前,我使用Tomcat将我的后端与RESTAPI一起保存。当我想使用我的前端时,我只是启动Tomcat,它保存后端项目,然后,我可以使用http请求通过RESTAPI访问后端。 现在我考虑摆脱Tomcat,将其部署为jar文件,而不是war文件,并通过Main方法在本地运行它。 我是这样做的(): 我的Rest课程摘录如下: @Path("/schemas") public class RestApi { @GET @Path("/hi") public String
@Path("/schemas")
public class RestApi {
@GET
@Path("/hi")
public String dropHi() {
return "hi;
}
}
运行这个main可以工作,但是由于某些原因仍然无法访问RESTAPI。当我试图通过联系http://localhost:8080/api/schemas/hi
在浏览器中,什么都不会发生。有什么不对劲的,我想做的事有意义吗?
我们的想法是以后在服务器上运行后端,而不使用Tomcat,只是将其作为jar文件运行,并通过前端访问它,您可以在您的系统上本地运行该前端。您尝试的操作是有意义的。你想要一个独立的服务器,这没有什么错 我做了类似的事情,但使用Jetty server和REST可以轻松实现REST。虽然我不确定所有的东西是否都适合您(很可能不是),但它仍然应该非常相似,因为Jersey REST和RESTEasy都是根据相同的规格制造的: 不管怎样,以下是对我有效的方法:
//Obviously main method from which you start the server
public static void main(String[] consoleArgs) {
final Server server= new Server(port);
final HandlerList handlers= new HandlerList();
addServlets(handlers);
server.setHandler(handlers);
server.start();
}
private static void addServlets(HandlerList handlers) {
final ServletContextHandler servletContextHandler= new ServletContextHandler(ServletContextHandler.SESSIONS);
servletContextHandler.setContextPath("/");
handlers.addHandler(servletContextHandler);
//handlers and servlets that I ommit...
addRestServiceContainer(servletContextHandler);
}
// and here is the trick...
// the settings you see here would normally go to web.xml file
private static void addRestServiceContainer(final ServletContextHandler servletContextHandler) {
ServletHolder holder= new ServletHolder(new HttpServlet30Dispatcher());
holder.setInitParameter("javax.ws.rs.Application", "com.stackoverflow.rest.application.RestfulServiceContainer");
holder.setInitParameter("resteasy.servlet.mapping.prefix", "/rest");
holder.setInitParameter("resteasy.providers", "org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider");
servletContextHandler.addServlet(holder, RestResourcePaths.REST_SERVICES_BASE_PATH + "/*");
}
最后,下面是com.stackoverflow.rest.application.RestfulServiceContainer
的外观:
public class RestfulServiceContainer extends Application {
private static final Set<Class<?>> fSingletons= new HashSet<Class<?>>();
private static final Set<Object> fRestfulServices= new HashSet<Object>();
public RestfulServiceContainer() {
registerServices();
initProviders();
}
/**
* Normally, when resteasy.scan is set to true all provider classes (with @Provider) are registered automatically,
* but since this is a standalone Jetty app it doesn't work. So, we register provider classes here manually.
*/
private void initProviders() {
fSingletons.add(TrafficInterceptor.class);
fSingletons.add(LogInterceptor.class);
fSingletons.add(RateLimitInterceptor.class);
fSingletons.add(SecurityInterceptor.class);
fSingletons.add(ExceptionHandler.class);
}
private void registerServices() {
fRestfulServices.add(new GetWhateverService());
fRestfulServices.add(new PostStuffService());
}
@Override
public Set<Class<?>> getClasses() {
return fSingletons;
}
@Override
public Set<Object> getSingletons() {
return fRestfulServices;
}
}
公共类RestfulServiceContainer扩展应用程序{
私有静态最终集>();
私有静态最终集fRestfulServices=newhashset();
公共RestfulServiceContainer(){
registerServices();
initProviders();
}
/**
*通常,当resteasy.scan设置为true时,所有提供程序类(带有@provider)都会自动注册,
*但由于这是一个独立的Jetty应用程序,它无法工作。因此,我们在这里手动注册提供程序类。
*/
私有void initProviders(){
add(TrafficInterceptor.class);
添加(LogInterceptor.class);
add(RateLimitInterceptor.class);
add(SecurityInterceptor.class);
添加(ExceptionHandler.class);
}
私有无效注册表服务(){
add(新的GetWhateverService());
添加(新的PostStuffService());
}
@凌驾
公共设置我做到了。有两个问题:
在我的web.xml中有/api/*
,它不再被使用,因此链接不再是http://localhost:8080/api/schemas/hi
,但http://localhost:8080/schemas/hi
在my web.xml中,我得到了以下条目:
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, POST, HEAD, PUT, DELETE</param-value>
</init-param>
</filter>
并在主方法中设置:
config.getContainerResponseFilters().add(CORSFilter.class);
首先,谢谢你。我想我发现了一些问题:Chrome告诉我“请求的资源上不存在访问控制允许源代码”标题。因此,不允许访问源代码“null”。当我使用Tomcat时,我在web.xml中添加了CORS。因此,也许这就是问题所在,我必须以某种方式将CORS添加到我的服务器设置中,这可能是吗?就像您在上面的评论中提到的“addRestServiceContainer()”中所做的那样。没错!添加到那里
public class CORSFilter implements ContainerResponseFilter {
public ContainerResponse filter(ContainerRequest req, ContainerResponse containerResponse) {
ResponseBuilder responseBuilder = Response.fromResponse(containerResponse.getResponse());
// *(allow from all servers) OR http://example.com/
responseBuilder.header("Access-Control-Allow-Origin", "*")
// As a part of the response to a request, which HTTP methods can be used during the actual request.
.header("Access-Control-Allow-Methods", "API, CRUNCHIFYGET, GET, POST, PUT, UPDATE, OPTIONS")
// How long the results of a request can be cached in a result cache.
.header("Access-Control-Max-Age", "151200")
// As part of the response to a request, which HTTP headers can be used during the actual request.
.header("Access-Control-Allow-Headers", "x-requested-with,Content-Type");
String requestHeader = req.getHeaderValue("Access-Control-Request-Headers");
if (null != requestHeader && !requestHeader.equals(null)) {
responseBuilder.header("Access-Control-Allow-Headers", requestHeader);
}
containerResponse.setResponse(responseBuilder.build());
return containerResponse;
}
}
config.getContainerResponseFilters().add(CORSFilter.class);