Jetty server configuration

2020-03-30 03:05发布

问题:

I use Jetty 9 and have some problems with configuration. I simple RESTs works fine. But the problem begun when I tried to add new headers to all requests and error handler. Only way I am able to handle headers it is by adding this code to every response:

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

Server configuration:

        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 class

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

    }

How to register headers? What am I doing wrong? I do not use WEB configuration.

回答1:

You are mixing Jersey 1.x with Jersey 2.x, which should not be done. Your filter class is based on Jersey 1.x. Your ResourceConfig is Jersey 2.x. I know this because Jersey 1.x ResourceConfig doesn't have the register() method. With Jersey 1.x, this is howwe would register your above filter

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

And that would be enough. But Jersey 2.x does not have this way of adding filters. We need to register everything.

That being said, if you are using Jersey 2.x, I highly suggest getting rid of all your Jersey 1.x dependencies. After doing so, the first thing you will notice is that your filter class will no longer compile. Here's how the refactored 2.x filter should look like:

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

Using the above filter should work.



回答2:

Similar approach as peeskillet mentioned, but I have held jetty configuration in jetty.xml in my application.

So to add custom filters I had to register them in the jetty.xml file as:

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