我在Jetty上使用Jersey2编写了一个基本的REST服务器,以测试HTTP Chunked Transfer-Encoding和gzip内容编码。但是我发现实现WriterInceptor以将GZIPOutputStream应用于gzip编码的推荐方法导致服务器阻塞而不是通过gzip的块发送。 我相信是GZIPOutputStream等待它自己的缓冲区填满,所以我尝试在WriterInterceptor中重写write()方法以在每次写入后强制刷新()(因为我的服务器总是一次写入一个块)但是没有不同。有没有办法在写入发生时强制刷新?
App.java
public class App
{
public static int lineCount=0;
public static void main( String[] args ) {
System.out.println( "Hello World!" );
ResourceConfig config = new ResourceConfig();
config.packages("com.example.mockAPIjava");
ServletHolder servlet = new ServletHolder(new ServletContainer(config));
EncodingFilter.enableFor(config, GZipEncoder.class);
Server server = new Server(2222);
ServletContextHandler context = new ServletContextHandler(server, "/*");
context.addServlet(servlet, "/*");
try {
server.start();
server.join();
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
server.destroy();
}
}
}
GZIPWriterInterceptor.java
@Provider
@Compress
public class GZIPWriterInterceptor implements WriterInterceptor {
@Override
public void aroundWriteTo(WriterInterceptorContext context)
throws IOException, WebApplicationException {
MultivaluedMap<String,Object> headers = context.getHeaders();
headers.add("Content-Encoding", "gzip");
final OutputStream outputStream = context.getOutputStream();
context.setOutputStream(new GZIPOutputStream(outputStream) {
@Override
public void write(final int b) throws IOException {
out.write(b);
out.flush();
}
@Override
public void write(final byte[] b) throws IOException {
out.write(b);
out.flush();
}
@Override
public void write(final byte[] b, final int off, final int len) throws IOException {
out.write(b, off, len);
out.flush();
}
});
context.proceed();
}
}
Resource.java
@Path("stream")
public class Resource {
@GET
@Path("test")
@Compress
@Produces(MediaType.APPLICATION_JSON)
public ChunkedOutput<String> helloWorld(@Context HttpHeaders header, @Context HttpServletResponse response) {
final ChunkedOutput<String> output = new ChunkedOutput<String>(String.class, "\r\n");
new Thread() {
public void run() {
BufferedReader br = null;
try {
String chunk;
// open file for reading
File file = new File("/tmp/stream.txt");
FileReader fr = new FileReader(file);
br = new BufferedReader(fr);
while ((chunk = getNextString(br)) != null) {
// write a chunk every second
output.write(chunk);
try {
Thread.sleep(1 * 1000);
} catch(InterruptedException ex) {
Thread.currentThread().interrupt();
}
}
} catch (Exception e) {
// IOException thrown when writing the
// chunks of response: should be handled
e.printStackTrace();
} finally {
try {
output.close();
// simplified: IOException thrown from
// this close() should be handled here...
if (br!=null) { br.close(); }
} catch (IOException e1){
e1.printStackTrace();
}
}
}
}.start();
// the output will be probably returned even before
// a first chunk is written by the new thread
return output;
}
private String getNextString(BufferedReader br) throws IOException, ParseException {
App.lineCount++;
return br.readLine();;
}
}
Compress.java
//@Compress annotation is the name binding annotation for the GZIPWriterInterceptor
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
public @interface Compress {}
答案 0 :(得分:0)
通过覆盖...
{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: [
{
loader: 'css-loader',
options: {
modules: true
}
},
'postcss-loader',
'sass-loader'
]
}),
},
...
的{{1}}方法,您刚刚停止了gzipping!
write
因为您已将其重写为而不是调用GZIPOutputStream
(您应该已经完成),而是public void write(final int b) throws IOException {
out.write(b);
out.flush();
}
,您将直接发送到上下文OutputStream,解压缩。
据推测,接收方期望gzip数据而不接收它,这可能会导致各种错误行为。
更改代码以调用super.write
和out.write
:
super.write
等