Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Late and safer response writes #605

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@
import br.com.caelum.vraptor.http.ParameterNameProvider;
import br.com.caelum.vraptor.http.ParametersProvider;
import br.com.caelum.vraptor.http.ParanamerNameProvider;
import br.com.caelum.vraptor.http.LateResponseCommitHandler;
import br.com.caelum.vraptor.http.UrlToResourceTranslator;
import br.com.caelum.vraptor.http.iogi.InstantiatorWithErrors;
import br.com.caelum.vraptor.http.iogi.IogiParametersProvider;
Expand Down Expand Up @@ -278,7 +279,8 @@ ProxyInitializer.class, getProxyInitializerImpl()
RestHeadersHandler.class, DefaultRestHeadersHandler.class,
FlashScope.class, SessionFlashScope.class,
XStreamConverters.class, XStreamConverters.class,
MessageConverter.class, MessageConverter.class
MessageConverter.class, MessageConverter.class,
LateResponseCommitHandler.class, LateResponseCommitHandler.class
);

@SuppressWarnings({"unchecked", "rawtypes"})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@
*/
package br.com.caelum.vraptor.core;

import java.io.IOException;

import br.com.caelum.vraptor.VRaptorException;
import br.com.caelum.vraptor.http.LateResponseCommitHandler;
import br.com.caelum.vraptor.interceptor.Interceptor;
import br.com.caelum.vraptor.interceptor.InterceptorRegistry;
import br.com.caelum.vraptor.ioc.PrototypeScoped;
Expand All @@ -31,17 +34,26 @@ public class EnhancedRequestExecution implements RequestExecution {

private final InterceptorRegistry registry;
private final InterceptorStack stack;
private final LateResponseCommitHandler responseHandler;

public EnhancedRequestExecution(InterceptorStack stack, InterceptorRegistry registry) {
this.stack = stack;
public EnhancedRequestExecution(InterceptorRegistry registry, InterceptorStack stack,
LateResponseCommitHandler responseHandler) {
this.registry = registry;
this.stack = stack;
this.responseHandler = responseHandler;
}


public void execute() throws VRaptorException {
for (Class<? extends Interceptor> interceptor : registry.all()) {
stack.add(interceptor);
}
stack.next(null, null);
try {
responseHandler.commit();
} catch (IOException e) {
throw new VRaptorException("IO error when commiting the response", e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package br.com.caelum.vraptor.http;

import static com.google.common.base.Preconditions.checkState;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletResponse;

import br.com.caelum.vraptor.ioc.Component;

@Component
public class LateResponseCommitHandler {

private final HttpServletResponse response;

private ByteArrayOutputStream stream;
private PrintWriter writer;

public LateResponseCommitHandler(HttpServletResponse response) {
this.response = response;
}

public void commit() throws IOException {
if (stream != null) {
writer.flush();
if (stream.size() > 0) {
stream.writeTo(response.getOutputStream());
writer.close();
}
}
}

public void writeJson(String data) {
write(data);
response.setContentType("application/json");
}

private void write(String data) {
checkState(stream == null, "response data was already wrote");
stream = new ByteArrayOutputStream(response.getBufferSize());
writer = new PrintWriter(stream);
writer.write(data);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,7 @@
*/
package br.com.caelum.vraptor.serialization.gson;

import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import br.com.caelum.vraptor.http.LateResponseCommitHandler;
import br.com.caelum.vraptor.interceptor.TypeNameExtractor;
import br.com.caelum.vraptor.ioc.Component;
import br.com.caelum.vraptor.serialization.JSONSerialization;
Expand All @@ -27,7 +24,6 @@
import br.com.caelum.vraptor.serialization.Serializer;
import br.com.caelum.vraptor.serialization.SerializerBuilder;
import br.com.caelum.vraptor.serialization.xstream.Serializee;
import br.com.caelum.vraptor.view.ResultException;

/**
* Gson implementation for JSONSerialization
Expand All @@ -39,7 +35,7 @@
@Component
public class GsonJSONSerialization implements JSONSerialization {

protected final HttpServletResponse response;
protected final LateResponseCommitHandler responseHandler;

protected final TypeNameExtractor extractor;

Expand All @@ -49,9 +45,9 @@ public class GsonJSONSerialization implements JSONSerialization {

protected final Serializee serializee;

public GsonJSONSerialization(HttpServletResponse response, TypeNameExtractor extractor,
public GsonJSONSerialization(LateResponseCommitHandler responseHandler, TypeNameExtractor extractor,
ProxyInitializer initializer, VRaptorGsonBuilder builder, Serializee serializee) {
this.response = response;
this.responseHandler = responseHandler;
this.extractor = extractor;
this.initializer = initializer;

Expand All @@ -68,16 +64,11 @@ public <T> Serializer from(T object) {
}

public <T> Serializer from(T object, String alias) {
response.setContentType("application/json");
return getSerializer().from(object, alias);
}

protected SerializerBuilder getSerializer() {
try {
return new GsonSerializer(builder, response.getWriter(), extractor, initializer, serializee);
} catch (IOException e) {
throw new ResultException("Unable to serialize data", e);
}
return new GsonSerializer(builder, responseHandler, extractor, initializer, serializee);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

import static com.google.common.base.Preconditions.checkNotNull;

import java.io.IOException;
import java.io.Writer;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
Expand All @@ -28,6 +26,7 @@
import java.util.Map;
import java.util.Set;

import br.com.caelum.vraptor.http.LateResponseCommitHandler;
import br.com.caelum.vraptor.interceptor.TypeNameExtractor;
import br.com.caelum.vraptor.serialization.ProxyInitializer;
import br.com.caelum.vraptor.serialization.Serializer;
Expand All @@ -45,7 +44,7 @@

public class GsonSerializer implements SerializerBuilder {

private final Writer writer;
private final LateResponseCommitHandler responseHandler;

private final TypeNameExtractor extractor;

Expand All @@ -55,9 +54,9 @@ public class GsonSerializer implements SerializerBuilder {

protected VRaptorGsonBuilder builder;

public GsonSerializer(VRaptorGsonBuilder builder, Writer writer, TypeNameExtractor extractor,
public GsonSerializer(VRaptorGsonBuilder builder, LateResponseCommitHandler responseHandler, TypeNameExtractor extractor,
ProxyInitializer initializer, Serializee serializee) {
this.writer = writer;
this.responseHandler = responseHandler;
this.extractor = extractor;
this.initializer = initializer;
this.builder = builder;
Expand Down Expand Up @@ -135,7 +134,6 @@ public Serializer include(String... fields) {
}

public void serialize() {
try {
Object root = serializee.getRoot();

builder.setExclusionStrategies(new Exclusions(serializee));
Expand All @@ -144,15 +142,12 @@ public void serialize() {

String alias = builder.getAlias();
if (builder.isWithoutRoot()) {
writer.write(gson.toJson(root));
responseHandler.writeJson(gson.toJson(root));
} else {
Map<String, Object> tree = new HashMap<String, Object>();
tree.put(alias, root);
writer.write(gson.toJson(tree));
responseHandler.writeJson(gson.toJson(tree));
}
} catch (IOException e) {
throw new RuntimeException("Não pode serializar", e);
}
}

public Serializer recursive() {
Expand Down