Skip to content
This repository was archived by the owner on May 28, 2018. It is now read-only.

Commit 4d41517

Browse files
author
Adam Lindenthal
committed
JERSEY-2524 Problem generating JSON w/Padding with GZIP compression
Change-Id: I3bf78ea2f998f2957a1ab5750ae76f3fe021fcbc
1 parent f076822 commit 4d41517

File tree

5 files changed

+224
-3
lines changed

5 files changed

+224
-3
lines changed
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3+
*
4+
* Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
5+
*
6+
* The contents of this file are subject to the terms of either the GNU
7+
* General Public License Version 2 only ("GPL") or the Common Development
8+
* and Distribution License("CDDL") (collectively, the "License"). You
9+
* may not use this file except in compliance with the License. You can
10+
* obtain a copy of the License at
11+
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
12+
* or packager/legal/LICENSE.txt. See the License for the specific
13+
* language governing permissions and limitations under the License.
14+
*
15+
* When distributing the software, include this License Header Notice in each
16+
* file and include the License file at packager/legal/LICENSE.txt.
17+
*
18+
* GPL Classpath Exception:
19+
* Oracle designates this particular file as subject to the "Classpath"
20+
* exception as provided by Oracle in the GPL Version 2 section of the License
21+
* file that accompanied this code.
22+
*
23+
* Modifications:
24+
* If applicable, add the following below the License Header, with the fields
25+
* enclosed by brackets [] replaced by your own identifying information:
26+
* "Portions Copyright [year] [name of copyright owner]"
27+
*
28+
* Contributor(s):
29+
* If you wish your version of this file to be governed by only the CDDL or
30+
* only the GPL Version 2, indicate your decision by adding "[Contributor]
31+
* elects to include this software in this distribution under the [CDDL or GPL
32+
* Version 2] license." If you don't indicate a single choice of license, a
33+
* recipient has the option to distribute your version of this file under
34+
* either the CDDL, the GPL Version 2 or to extend the choice of license to
35+
* its licensees as provided above. However, if you add GPL Version 2 code
36+
* and therefore, elected the GPL Version 2 license, then the option applies
37+
* only if the new code is made subject to such option by the copyright
38+
* holder.
39+
*/
40+
package org.glassfish.jersey;
41+
42+
import javax.ws.rs.Priorities;
43+
44+
/**
45+
* Built-in Jersey-specific priority constants to be used along with {@link javax.ws.rs.Priorities} where finer-grained
46+
* categorization is required.
47+
*
48+
* @author Adam Lindenthal (adam.lindenthal at oracle.com)
49+
*/
50+
public class JerseyPriorities {
51+
52+
private JerseyPriorities() {
53+
// prevents instantiation
54+
}
55+
56+
/**
57+
* Priority for components that have to be called AFTER message encoders/decoders filters/interceptors.
58+
* The constant has to be higher than {@link javax.ws.rs.Priorities#ENTITY_CODER} in order to force the
59+
* processing after the components with {@code Priorities.ENTITY_CODER} are processed.
60+
*/
61+
public static final int POST_ENTITY_CODER = Priorities.ENTITY_CODER + 100;
62+
}

core-common/src/main/java/org/glassfish/jersey/message/DeflateEncoder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33
*
4-
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2012-2014 Oracle and/or its affiliates. All rights reserved.
55
*
66
* The contents of this file are subject to the terms of either the GNU
77
* General Public License Version 2 only ("GPL") or the Common Development
@@ -48,6 +48,8 @@
4848
import java.util.zip.Inflater;
4949
import java.util.zip.InflaterInputStream;
5050

51+
import javax.annotation.Priority;
52+
import javax.ws.rs.Priorities;
5153
import javax.ws.rs.core.Configuration;
5254

5355
import javax.inject.Inject;
@@ -62,6 +64,7 @@
6264
*
6365
* @author Martin Matula (martin.matula at oracle.com)
6466
*/
67+
@Priority(Priorities.ENTITY_CODER)
6568
public class DeflateEncoder extends ContentEncoder {
6669

6770
// TODO This provider should be registered and configured via a feature.

core-common/src/main/java/org/glassfish/jersey/message/GZipEncoder.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/*
22
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
33
*
4-
* Copyright (c) 2012 Oracle and/or its affiliates. All rights reserved.
4+
* Copyright (c) 2012-2014 Oracle and/or its affiliates. All rights reserved.
55
*
66
* The contents of this file are subject to the terms of either the GNU
77
* General Public License Version 2 only ("GPL") or the Common Development
@@ -45,6 +45,8 @@
4545
import java.util.zip.GZIPInputStream;
4646
import java.util.zip.GZIPOutputStream;
4747

48+
import javax.annotation.Priority;
49+
import javax.ws.rs.Priorities;
4850
import javax.ws.rs.core.HttpHeaders;
4951

5052
import org.glassfish.jersey.spi.ContentEncoder;
@@ -55,6 +57,7 @@
5557
*
5658
* @author Martin Matula (martin.matula at oracle.com)
5759
*/
60+
@Priority(Priorities.ENTITY_CODER)
5861
public class GZipEncoder extends ContentEncoder {
5962
/**
6063
* Initialize GZipEncoder.

core-server/src/main/java/org/glassfish/jersey/server/internal/JsonWithPaddingInterceptor.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import javax.inject.Inject;
5959
import javax.inject.Provider;
6060

61+
import org.glassfish.jersey.JerseyPriorities;
6162
import org.glassfish.jersey.server.ContainerRequest;
6263
import org.glassfish.jersey.server.JSONP;
6364

@@ -71,7 +72,9 @@
7172
* @author Michal Gajdos (michal.gajdos at oracle.com)
7273
* @see JSONP
7374
*/
74-
@Priority(Priorities.HEADER_DECORATOR)
75+
@Priority(JerseyPriorities.POST_ENTITY_CODER)
76+
// this interceptor has to run after content encoders (e.g. gzip/deflate), otherwise the added content (padding with the callback
77+
// method call would not be encoded.
7578
public class JsonWithPaddingInterceptor implements WriterInterceptor {
7679

7780
private static final Map<String, Set<String>> JAVASCRIPT_TYPES;
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/*
2+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3+
*
4+
* Copyright (c) 2014 Oracle and/or its affiliates. All rights reserved.
5+
*
6+
* The contents of this file are subject to the terms of either the GNU
7+
* General Public License Version 2 only ("GPL") or the Common Development
8+
* and Distribution License("CDDL") (collectively, the "License"). You
9+
* may not use this file except in compliance with the License. You can
10+
* obtain a copy of the License at
11+
* http://glassfish.java.net/public/CDDL+GPL_1_1.html
12+
* or packager/legal/LICENSE.txt. See the License for the specific
13+
* language governing permissions and limitations under the License.
14+
*
15+
* When distributing the software, include this License Header Notice in each
16+
* file and include the License file at packager/legal/LICENSE.txt.
17+
*
18+
* GPL Classpath Exception:
19+
* Oracle designates this particular file as subject to the "Classpath"
20+
* exception as provided by Oracle in the GPL Version 2 section of the License
21+
* file that accompanied this code.
22+
*
23+
* Modifications:
24+
* If applicable, add the following below the License Header, with the fields
25+
* enclosed by brackets [] replaced by your own identifying information:
26+
* "Portions Copyright [year] [name of copyright owner]"
27+
*
28+
* Contributor(s):
29+
* If you wish your version of this file to be governed by only the CDDL or
30+
* only the GPL Version 2, indicate your decision by adding "[Contributor]
31+
* elects to include this software in this distribution under the [CDDL or GPL
32+
* Version 2] license." If you don't indicate a single choice of license, a
33+
* recipient has the option to distribute your version of this file under
34+
* either the CDDL, the GPL Version 2 or to extend the choice of license to
35+
* its licensees as provided above. However, if you add GPL Version 2 code
36+
* and therefore, elected the GPL Version 2 license, then the option applies
37+
* only if the new code is made subject to such option by the copyright
38+
* holder.
39+
*/
40+
package org.glassfish.jersey.tests.e2e.json;
41+
42+
import java.util.logging.Logger;
43+
44+
import javax.ws.rs.GET;
45+
import javax.ws.rs.Path;
46+
import javax.ws.rs.Produces;
47+
import javax.ws.rs.core.Context;
48+
import javax.ws.rs.core.HttpHeaders;
49+
import javax.ws.rs.core.MultivaluedMap;
50+
import javax.ws.rs.core.Response;
51+
52+
import org.glassfish.jersey.jackson.JacksonFeature;
53+
import org.glassfish.jersey.message.DeflateEncoder;
54+
import org.glassfish.jersey.message.GZipEncoder;
55+
import org.glassfish.jersey.server.JSONP;
56+
import org.glassfish.jersey.server.ResourceConfig;
57+
import org.glassfish.jersey.server.filter.EncodingFilter;
58+
import org.glassfish.jersey.test.JerseyTest;
59+
import org.glassfish.jersey.test.TestProperties;
60+
61+
import org.junit.Test;
62+
63+
import static org.junit.Assert.assertEquals;
64+
import static org.junit.Assert.assertTrue;
65+
66+
/**
67+
* Tests, that JSONP callback wrapping takes places before the eventual entity compression.
68+
*
69+
* See https://java.net/jira/browse/JERSEY-2524 for the original issue description.
70+
*
71+
* @author Adam Lindenthal (adam.lindenthal at oracle.com)
72+
*/
73+
public class JsonWithPaddingEncodingFilterTest extends JerseyTest {
74+
private static final Logger LOGGER = Logger.getLogger(JsonWithPaddingEncodingFilterTest.class.getName());
75+
76+
@Override
77+
protected ResourceConfig configure() {
78+
enable(TestProperties.LOG_TRAFFIC);
79+
return new ResourceConfig(MyResource.class)
80+
.register(JacksonFeature.class)
81+
.register(EncodingFilter.class)
82+
.register(GZipEncoder.class)
83+
.register(DeflateEncoder.class);
84+
}
85+
86+
@Path("rest")
87+
public static class MyResource {
88+
@GET
89+
@Path("jsonp")
90+
@JSONP(queryParam = JSONP.DEFAULT_QUERY)
91+
@Produces("application/x-javascript")
92+
public Message getHelloJsonP(@Context HttpHeaders headers) {
93+
MultivaluedMap<String, String> headerParams = headers.getRequestHeaders();
94+
for (String key : headerParams.keySet()) {
95+
System.out.println(key + ": ");
96+
for (String value : headerParams.get(key)) {
97+
System.out.print(value + ", ");
98+
}
99+
System.out.println("\b\b");
100+
}
101+
return new Message("Hello world JsonP!", "English");
102+
}
103+
}
104+
105+
public static class Message {
106+
private String greeting;
107+
private String language;
108+
109+
public Message(String greeting, String language) {
110+
this.greeting = greeting;
111+
this.language = language;
112+
}
113+
114+
public String getGreeting() {
115+
return greeting;
116+
}
117+
118+
public String getLanguage() {
119+
return language;
120+
}
121+
}
122+
123+
@Test
124+
public void testCorrectGzipDecoding() {
125+
final Response response = target().path("rest/jsonp").queryParam("__callback", "dialog")
126+
.register(GZipEncoder.class).request("application/x-javascript")
127+
.header("Accept-Encoding", "gzip").get();
128+
129+
String result = response.readEntity(String.class);
130+
assertEquals("gzip", response.getHeaders().getFirst("Content-Encoding"));
131+
132+
assertTrue(result.startsWith("dialog("));
133+
assertTrue(result.contains("Hello world JsonP!"));
134+
assertTrue(result.contains("English"));
135+
}
136+
137+
@Test
138+
public void testCorrectDeflateDecoding() {
139+
final Response response = target().path("rest/jsonp").queryParam("__callback", "dialog")
140+
.register(DeflateEncoder.class).request("application/x-javascript")
141+
.header("Accept-Encoding", "deflate").get();
142+
143+
String result = response.readEntity(String.class);
144+
assertEquals("deflate", response.getHeaders().getFirst("Content-Encoding"));
145+
146+
assertTrue(result.startsWith("dialog("));
147+
assertTrue(result.contains("Hello world JsonP!"));
148+
assertTrue(result.contains("English"));
149+
}
150+
}

0 commit comments

Comments
 (0)