Конфигурация джетти-сервера

Я использую Jetty 9 и у меня есть некоторые проблемы с настройкой. У меня простой REST работает нормально. Но проблема началась, когда я попытался добавить новые заголовки ко всем запросам и обработчику ошибок. Единственный способ, которым я могу обрабатывать заголовки, - это добавлять этот код к каждому ответу:

return Response.ok(murals)
                .header("Access-Control-Allow-Origin", "*")
                .header("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT")
                .build(); 

Конфигурация сервера:

        Server server = new Server(9998);
        ServletContextHandler servletContextHandler = new ServletContextHandler(server, "/", ServletContextHandler.SESSIONS);

        servletContextHandler.addFilter(GuiceFilter.class, "/*", EnumSet.allOf(DispatcherType.class));
        servletContextHandler.addServlet(DefaultServlet.class, "/");

        ResourceConfig rc = new ResourceConfig()
                .register(FilterHeaders.class)
                .register(ExceptionNotFound.class)
                .register(CORSFilter.class); //doesnt work
        new ServletHolder(new ServletContainer(rc));

        HandlerWrapper han = new HandlerWrapper();
        han.setHandler(new AbstractHandler() {

            @Override
            public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
               request.setAttribute("welcome","Hello"); //doesn't work
            }
        });

        servletContextHandler.addFilter(Filters.class, "/*", EnumSet.of(DispatcherType.REQUEST)); //doesnt work

        ResourceHandler resourceHandler = resourceHandler();
        servletContextHandler.setHandler(resourceHandler);
        servletContextHandler.setHandler(han);
        server.start();
        server.join();

Класс CROSFilter

 public class CORSFilter implements ContainerResponseFilter {

        @Override
        public ContainerResponse filter(ContainerRequest request,
                ContainerResponse response) {

            response.getHttpHeaders().add("Access-Control-Allow-Origin", "*");
            response.getHttpHeaders().add("Access-Control-Allow-Headers",
                    "origin, content-type, accept, authorization");
            response.getHttpHeaders().add("Access-Control-Allow-Credentials", "true");
            response.getHttpHeaders().add("Access-Control-Allow-Methods",
                    "GET, POST, PUT, DELETE, OPTIONS, HEAD");

            return response;
        }

    }

Как зарегистрировать заголовки? Что я делаю не так? Я не использую WEB-конфигурацию.


person Quark986    schedule 05.12.2014    source источник


Ответы (2)


Вы смешиваете Джерси 1.x с Джерси 2.x, чего нельзя делать. Ваш класс фильтра основан на Джерси 1.x. Ваш ResourceConfig — Джерси 2.x. Я знаю это, потому что в Джерси 1.x ResourceConfig нет метода register(). В случае Джерси 1.x мы бы зарегистрировали указанный выше фильтр следующим образом.

resourceConfig.getContainerResponseFilters().add(new CORSFilter());

И этого было бы достаточно. Но в Jersey 2.x нет такого способа добавления фильтров. Нам нужно register все.

При этом, если вы используете Jersey 2.x, я настоятельно рекомендую избавиться от всех ваших зависимостей от Jersey 1.x. После этого первое, что вы заметите, это то, что ваш класс фильтра больше не будет компилироваться. Вот как должен выглядеть переработанный фильтр 2.x:

import java.io.IOException;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;

@Provider
public class CORSFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext request,
            ContainerResponseContext response) throws IOException {
        response.getHeaders().add("Access-Control-Allow-Origin", "*");
        response.getHeaders().add("Access-Control-Allow-Headers",
                "origin, content-type, accept, authorization");
        response.getHeaders().add("Access-Control-Allow-Credentials", "true");
        response.getHeaders().add("Access-Control-Allow-Methods",
                "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    }
}

Использование вышеуказанного фильтра должно работать.

person Paul Samsotha    schedule 06.12.2014
comment
Нет ли случаев, когда использование * для Access-Control-Allow-Origin не сработает? - person gouessej; 21.05.2016

Аналогичный подход, как упоминалось в peeskillet, но я сохранил конфигурацию причала в jetty.xml в своем приложении.

Поэтому, чтобы добавить пользовательские фильтры, мне пришлось зарегистрировать их в файле jetty.xml как:

<New class="org.eclipse.jetty.servlet.ServletHolder">
<Arg>
    <New class="com.sun.jersey.spi.container.servlet.ServletContainer">
        <Arg>
            <New class="com.sun.jersey.api.core.PackagesResourceConfig">
                <Arg>
                    <Map>
                      <Entry>
                        <Item>com.sun.jersey.config.property.packages</Item>
                        <Item>...my package</Item>
                      </Entry>
                      <Entry>
                        <Item>com.sun.jersey.spi.container.ContainerResponseFilters</Item>
                        <Item>...MyCorsResponseFilter</Item>
                      </Entry>
                    </Map>
                </Arg>
            </New>
        </Arg>
    </New>
</Arg>

person mpasko256    schedule 01.11.2015