2015-07-30 2 views
0

В настоящее время я использую Tomcat, чтобы поддерживать мой Backend вместе с моим API-интерфейсом Rest. Когда я хочу использовать мой Frontend, я просто запускаю Tomcat, который содержит Backend-Project, а затем я могу получить доступ к бэкэнду через Rest-API с помощью http-запросов. Теперь я подумал о том, чтобы избавиться от Tomcat и развернуть его как файл jar вместо файла войны и запустить его локально с помощью метода Main. Я сделал это так (Source):Запуск API Джерси-Остатка без использования контейнера в качестве банки

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-класса будет:

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

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

Запуск это основные работы, но по каким-то причинам до сих пор не может получить доступ Rest-Api. Когда я пытаюсь получить «привет», пытаясь достичь http://localhost:8080/api/schemas/hi, в браузере ничего не происходит. Что может быть неправильным, делает ли он даже то, что я пытаюсь сделать? Идея состоит в том, чтобы запустить бэкэнд позже на сервере без использования Tomcat, просто запустив его как файл jar и получив доступ к нему через интерфейс, который вы запускаете локально в своей системе.

ответ

1

я это сделал. Были две проблемы:

  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> 
    

    Не используя контейнер больше я должен был позволить Корс другому. В конце концов я сделал это с помощью 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; 
        } 
    } 
    

    и установить его в главном методе:

    config.getContainerResponseFilters().add(CORSFilter.class); 
    
2

Что вы пытаетесь сделать, имеет смысл. Вы хотите автономный сервер, и нет ничего плохого в этом.

Я сделал аналогичные вещи, но с сервером Jetty и реализацией RESTEasy REST. Хотя я не уверен, что все будет работать из коробки для вас (скорее всего, нет), все равно это должно быть очень похоже на то, что как Джерси REST, так и RESTEasy построены в соответствии с теми же характеристиками: https://jcp.org/en/jsr/detail?id=311

Anyways, вот что работает для меня:

//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; 
} 

} 
+0

Спасибо, в первую очередь. Я думаю, что я что-то понял: Chrome говорит мне, что заголовок «Нет доступа-Контроль-Разрешить-Происхождение» присутствует на запрошенном ресурсе. Поэтому исходный «нуль» не имеет доступа ». Когда я использовал Tomcat, я добавил CORS в web.xml. Так что, возможно, это проблема, я должен как-то добавить CORS в настройки моего сервера, может быть? – testiguy

+0

Как вы это делали в 'addRestServiceContainer() ', упомянутом в комментарии выше. – testiguy

+0

Ровно! Добавьте его туда – darijan

Смежные вопросы