簡體   English   中英

在不使用容器作為jar的情況下運行Jersey Rest API

[英]Running Jersey Rest API without using container as jar

目前,我正在使用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(); 
   }

我的休息班的摘要是:

@Path("/schemas")
public class RestApi {

    @GET
    @Path("/hi")
    public String dropHi() {
        return "hi;
    }
}

運行此主要程序有效,但由於某些原因仍無法訪問Rest-Api。 當我嘗試通過在瀏覽器中訪問http://localhost:8080/api/schemas/hi來獲得“ hi”時,什么都沒有發生。 可能出什么問題了,它甚至使我明白要做什么嗎? 這個想法是稍后在不使用Tomcat的服務器上運行后端,僅將其作為jar文件運行,並通過您在系統本地運行的前端進行訪問。

您正在嘗試做的事情很有道理。 您需要一台獨立服務器,這沒有任何問題。

我做了類似的事情,但是使用了Jetty服務器和REST的RESTEasy實現。 盡管我不確定一切是否都能為您工作(很可能不是),但仍然應該非常相似,因為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. 在我的web.xml中,有<url-pattern>/api/*</url-pattern> ,它不再使用了,因此鏈接不是http://localhost:8080/api/schemas/hi ,但是http://localhost:8080/schemas/hi

  2. 在我的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。 最終,我借助這樣的幫助完成了該操作

     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); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM