目前,我正在使用Tomcat将我的后端与我的Rest API保持一致。当我想使用我的前端时,我只是启动Tomcat,它拥有Backend-Project然后,我可以使用http-requests访问Rest-API的后端。 现在我考虑摆脱Tomcat并将其部署为jar文件,而不是war文件,并通过Main方法在本地运行它。 我这样做了(Source):
public class Main {
public static void main(String[] args) throws Exception {
ResourceConfig config = new DefaultResourceConfig(RestApi.class);
HttpServer server = HttpServerFactory.create("http://localhost:8080/", config);
server.start();
}
我的Rest-Class的摘录将是:
@Path("/schemas")
public class RestApi {
@GET
@Path("/hi")
public String dropHi() {
return "hi;
}
}
运行此主程序,但由于某种原因仍然无法访问Rest-Api。当我试图通过尝试在浏览器中访问http://localhost:8080/api/schemas/hi
来获得“hi”时,没有任何反应。可能有什么不对,它甚至会让我想要做什么?
我的想法是稍后在服务器上运行后端,而不使用Tomcat,只需将其作为jar文件运行,然后通过您在系统本地运行的前端访问它。
答案 0 :(得分:2)
你想要做的事情是有道理的。您需要独立服务器,并且没有任何问题。
我做了类似的事情,但是使用了Jetty服务器和RESTEasy REST实现。虽然我不确定一切都会为您开箱即用(很可能不是)但它应该仍然非常相似,因为Jersey REST和RESTEasy都是根据相同的规格构建的:https://jcp.org/en/jsr/detail?id=311
无论如何,这对我有用:
//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;
}
}
答案 1 :(得分:1)
我做到了。有两个问题:
在我的web.xml中有<url-pattern>/api/*</url-pattern>
,它已不再使用,因此链接不是http://localhost:8080/api/schemas/hi
,而是http://localhost:8080/schemas/hi
。
在我的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>
不再使用容器,我必须以另一种方式启用CORS。最后,我在this的帮助下做到了这一点:
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;
}
}
并在Main方法中设置:
config.getContainerResponseFilters().add(CORSFilter.class);