Server Sent Event Client with additional Cookie

前端 未结 2 1715
梦毁少年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:39

    Here's what's happens within EventSource to establish a conection to the given WebTarget:

           private Invocation.Builder prepareHandshakeRequest() {
                Invocation.Builder request = EventSource.this.target
                        .request(new MediaType[] { SseFeature.SERVER_SENT_EVENTS_TYPE });
                if ((this.lastEventId != null) && (!(this.lastEventId.isEmpty()))) {
                    request.header("Last-Event-ID", this.lastEventId);
                }
                if (EventSource.this.disableKeepAlive) {
                    request.header("Connection", "close");
                }
                return request;
              }
    

    As we can see - no chance to add a cookie here.

    So WebTarget.request(new MediaType[] { SseFeature.SERVER_SENT_EVENTS_TYPE }) needs to return a Builder that already has that desired cookie added.

    Consider this delegating class adding the desired cookie to all request* type methods:

    public class CookieAddedWebTarget implements WebTarget {
    
        private WebTarget base;
    
        private Cookie cookie;
    
        public CookieAddedWebTarget(WebTarget base, Cookie cookie) {
            this.base = base;
            this.cookie = cookie;
        }
    
        // Inject that cookie whenever someone requests a Builder (like EventSource does):
        public Builder request() {
            return base.request().cookie(cookie);
        }
    
        public Builder request(String... paramArrayOfString) {
            return base.request(paramArrayOfString).cookie(cookie);
        }
    
        public Builder request(MediaType... paramArrayOfMediaType) {
            return base.request(paramArrayOfMediaType).cookie(cookie);
        }
    
        public Configuration getConfiguration() {
            return base.getConfiguration();
        }
    
        //All other methods from WebTarget are delegated as-is:
    
        public URI getUri() {
            return base.getUri();
        }
    
        public UriBuilder getUriBuilder() {
            return base.getUriBuilder();
        }
    
        public WebTarget path(String paramString) {
            return base.path(paramString);
        }
    
        public WebTarget matrixParam(String paramString, Object... paramArrayOfObject) {
            return base.matrixParam(paramString, paramArrayOfObject);
        }
    
        public WebTarget property(String paramString, Object paramObject) {
            return base.property(paramString, paramObject);
        }
    
        public WebTarget queryParam(String paramString, Object... paramArrayOfObject) {
            return base.queryParam(paramString, paramArrayOfObject);
        }
    
        public WebTarget register(Class paramClass, Class... paramArrayOfClass) {
            return base.register(paramClass, paramArrayOfClass);
        }
    
        public WebTarget register(Class paramClass, int paramInt) {
            return base.register(paramClass, paramInt);
        }
    
        public WebTarget register(Class paramClass, Map, Integer> paramMap) {
            return base.register(paramClass, paramMap);
        }
    
        public WebTarget register(Class paramClass) {
            return base.register(paramClass);
        }
    
        public WebTarget register(Object paramObject, Class... paramArrayOfClass) {
            return base.register(paramObject, paramArrayOfClass);
        }
    
        public WebTarget register(Object paramObject, int paramInt) {
            return base.register(paramObject, paramInt);
        }
    
        public WebTarget register(Object paramObject, Map, Integer> paramMap) {
            return base.register(paramObject, paramMap);
        }
    
        public WebTarget register(Object paramObject) {
            return base.register(paramObject);
        }
    
        public WebTarget resolveTemplate(String paramString, Object paramObject) {
            return base.resolveTemplate(paramString, paramObject);
        }
    
        public WebTarget resolveTemplate(String paramString, Object paramObject, boolean paramBoolean) {
            return base.resolveTemplate(paramString, paramObject, paramBoolean);
        }
    
        public WebTarget resolveTemplateFromEncoded(String paramString, Object paramObject) {
            return base.resolveTemplateFromEncoded(paramString, paramObject);
        }
    
        public WebTarget resolveTemplates(Map paramMap) {
            return base.resolveTemplates(paramMap);
        }
    
        public WebTarget resolveTemplates(Map paramMap, boolean paramBoolean) {
            return base.resolveTemplates(paramMap, paramBoolean);
        }
    
        public WebTarget resolveTemplatesFromEncoded(Map paramMap) {
            return base.resolveTemplatesFromEncoded(paramMap);
        }
    
    }
    

    Now you should be able to reerite your test to:

    EventSource eventSource = EventSource.target(new CookieAddedWebTarget(target, 
                                new Cookie("name", "value"))).build();
    

    And the cookie should be inserted.

    Caveat: I have no way of testing this. Solution based only on reading source-code of jersey-media-sse-2.22.1.

    Good Luck.

提交回复
热议问题