Server Sent Event Client with additional Cookie

前端 未结 2 1707
梦毁少年i
梦毁少年i 2020-12-17 18:04

I am trying to unit test a Server Sent Event resource with an additional cookie. I am already using Jersey for the EventSource and JavaX for the client. The following code w

2条回答
  •  一整个雨季
    2020-12-17 18:55

    You could set the cookie in a ClientRequestFilter. Though the getCookies() on the ClientRequestContext is immutable, you should remember that a cookie is technically nothing more than a header. And the headers map on the request context is mutable. So you could do something like

    public static class SseCookieFilter implements ClientRequestFilter {
    
        @Override
        public void filter(ClientRequestContext requestContext) throws IOException {
            Cookie cookie = new Cookie("foo", "bar");
            requestContext.getHeaders().add("Cookie", cookie.toString());
        }
    }
    

    Just register the filter with the client (client.register(new SseCookieFilter())). It would be the same result as if you were to do

    target.(...).request().cookie("foo", "bar");
    

    Here is a complete example using Jersey Test Framework

    public class SseCookieFilterTest extends JerseyTest {
    
        @Path("events")
        public static class SseResource {
    
            @GET
            @Produces(SseFeature.SERVER_SENT_EVENTS)
            public EventOutput getServerSentEvents(@CookieParam("foo") String foo) {
                final EventOutput eventOutput = new EventOutput();
                new Thread(() -> {
                    try {
                        final OutboundEvent.Builder eventBuilder
                                = new OutboundEvent.Builder();
                        eventBuilder.name("message");
                        eventBuilder.data(String.class, "Blah " + foo + "!!!");
                        final OutboundEvent event = eventBuilder.build();
                        eventOutput.write(event);
    
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    } finally {
                        try {
                            eventOutput.close();
                        } catch (IOException ioClose) {
                            throw new RuntimeException(ioClose);
                        }
                    }
                }).start();
                return eventOutput;
            }
        }
    
        public static class SseCookieFilter implements ClientRequestFilter {
    
            @Override
            public void filter(ClientRequestContext requestContext) throws IOException {
                Cookie cookie = new Cookie("foo", "bar");
                requestContext.getHeaders().add("Cookie", cookie.toString());
            }
        }
    
        @Override
        public ResourceConfig configure() {
            return new ResourceConfig(SseResource.class)
                    .register(new LoggingFilter());
        }
    
        @Test
        public void doit() throws Exception {
            Client client = ClientBuilder.newBuilder()
                    .register(SseFeature.class).build();
            client.register(new SseCookieFilter());
            WebTarget target = client.target("http://localhost:9998/events");
            EventSource eventSource = EventSource.target(target).build();
            EventListener listener = (InboundEvent inboundEvent) -> {
                System.out.println("From server ---====++++>  " 
                        + inboundEvent.readData(String.class));
            };
            eventSource.register(listener, "message");
            eventSource.open();
            Thread.sleep(100);
            eventSource.close();
        }
    }
    

    These are the only dependencies needed to test

    
        org.glassfish.jersey.test-framework.providers
        jersey-test-framework-provider-grizzly2
        ${jersey2.version}
        test
    
    
        org.glassfish.jersey.media
        jersey-media-sse
        ${jersey2.version}
        test
    
    

    Here is the server side result from the LoggingFilter I registered on the server in the test

    INFO: 1 * Server has received a request on thread grizzly-http-server-2
    1 > GET http://localhost:9998/events
    1 > accept: text/event-stream
    1 > connection: close
    1 > cookie: $Version=1;foo=bar
    1 > host: localhost:9998
    1 > user-agent: Jersey/2.19 (HttpUrlConnection 1.8.0_31)
    
    INFO: 1 * Server responded with a response on thread grizzly-http-server-2
    1 < 200
    1 < Content-Type: text/event-stream
    
    From server ---====++++>  Blah bar!!!
    

提交回复
热议问题