Skip to content

Commit

Permalink
Added JsonView wrapper support.
Browse files Browse the repository at this point in the history
  • Loading branch information
noboomu committed May 17, 2019
1 parent d024cc1 commit 0fbc2ae
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import io.sinistral.proteus.server.endpoints.EndpointInfo;
import io.sinistral.proteus.services.BaseService;
import io.sinistral.proteus.services.DefaultService;
import io.sinistral.proteus.wrappers.JsonViewWrapper;
import io.undertow.server.DefaultResponseListener;
import io.undertow.server.HandlerWrapper;
import io.undertow.server.HttpHandler;
Expand All @@ -33,6 +34,7 @@
public class ApplicationModule extends AbstractModule
{
private static Logger log = LoggerFactory.getLogger(ApplicationModule.class.getCanonicalName());

protected Set<EndpointInfo> registeredEndpoints = new TreeSet<>();
protected Set<Class<?>> registeredControllers = new HashSet<>();
protected Set<Class<? extends BaseService>> registeredServices = new HashSet<>();
Expand Down Expand Up @@ -83,6 +85,7 @@ public void bindMappers()

this.requestStaticInjection(Extractors.class);
this.requestStaticInjection(ServerResponse.class);
this.requestStaticInjection(JsonViewWrapper.class);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ public class Extractors
private static Logger log = LoggerFactory.getLogger(Extractors.class.getCanonicalName());

@Inject
public static XmlMapper XML_MAPPER;
private static XmlMapper XML_MAPPER;

@Inject
public static ObjectMapper OBJECT_MAPPER;
private static ObjectMapper OBJECT_MAPPER;

public static JsonNode parseJson(byte[] bytes)
private static JsonNode parseJson(byte[] bytes)
{
try {
return OBJECT_MAPPER.readTree(bytes);
Expand All @@ -71,7 +71,6 @@ public static java.util.Optional<JsonNode> jsonNode(final HttpServerExchange exc
public static <T> java.util.Optional<T> model(final HttpServerExchange exchange, final TypeReference<T> type)
{
if (ServerPredicates.XML_PREDICATE.resolve(exchange)) {

return xmlModel(exchange, type);
} else {
return jsonModel(exchange, type);
Expand Down
16 changes: 14 additions & 2 deletions core/src/main/java/io/sinistral/proteus/server/ServerResponse.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.google.inject.Inject;
import io.sinistral.proteus.server.predicates.ServerPredicates;
import io.sinistral.proteus.wrappers.JsonViewWrapper;
import io.undertow.io.IoCallback;
import io.undertow.server.DefaultResponseListener;
import io.undertow.server.HttpHandler;
Expand Down Expand Up @@ -623,10 +624,21 @@ public void send(final HttpHandler handler, final HttpServerExchange exchange) t
exchange.getResponseSender().send(ByteBuffer.wrap(XML_MAPPER.writeValueAsBytes(this.entity)));
} else {

exchange.getResponseSender().send(ByteBuffer.wrap(OBJECT_MAPPER.writeValueAsBytes(this.entity)));
}
final Class jsonViewClass = exchange.getAttachment(JsonViewWrapper.JSON_VIEW_KEY);

if(jsonViewClass != null)
{
exchange.getResponseSender().send(ByteBuffer.wrap(OBJECT_MAPPER.writerWithView(jsonViewClass).writeValueAsBytes(this.entity)));
}
else
{
exchange.getResponseSender().send(ByteBuffer.wrap(OBJECT_MAPPER.writeValueAsBytes(this.entity)));
}

}

} catch (Exception e) {

log.error(e.getMessage() + " for entity " + this.entity, e);

throw new IllegalArgumentException(e);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package io.sinistral.proteus.wrappers;

import com.google.inject.Inject;
import io.undertow.server.HandlerWrapper;
import io.undertow.server.HttpHandler;
import io.undertow.util.AttachmentKey;

import javax.inject.Named;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;

public class JsonViewWrapper implements HandlerWrapper
{
public static AttachmentKey<Class> JSON_VIEW_KEY = AttachmentKey.create(Class.class);

@Named("jackson.jsonView.className")
@Inject(optional = true)
private static String VIEW_CLASS_NAME;

@Named("jackson.jsonView.queryParameterName")
@Inject(optional = true)
private static String QUERY_PARAMETER_NAME = "context";

private static Map<String, Class> CLASS_MAP;

public JsonViewWrapper()
{
super();

if (CLASS_MAP == null && VIEW_CLASS_NAME != null) {

try {

Class clazz = Class.forName(VIEW_CLASS_NAME);

CLASS_MAP = new HashMap<>();

final Class[] contexts = clazz.getClasses();

for (Class c : contexts) {
CLASS_MAP.put(c.getSimpleName().toLowerCase(), c);
}

} catch (Exception e) {
e.printStackTrace();
}
}
}

@Override
public HttpHandler wrap(HttpHandler handler)
{
return exchange -> {

if (CLASS_MAP != null) {

Optional.ofNullable(exchange.getQueryParameters().get(QUERY_PARAMETER_NAME))
.filter(q -> q.size() > 0)
.map(Deque::getFirst)
.ifPresent(cn -> {

Class viewClass = CLASS_MAP.get(cn);

exchange.putAttachment(JSON_VIEW_KEY, viewClass);
});
}

handler.handleRequest(exchange);
};
}
}
11 changes: 11 additions & 0 deletions core/src/main/resources/reference.conf
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@ openapi {
]
}

jackson {

jsonView = {
# a class that provides a mapping from the JsonView query parameter values to JsonView classes
className = null
# the name of the query parameter to use for JsonView class lookup
queryParameterName = "context"
}

}


swagger {

Expand Down

0 comments on commit 0fbc2ae

Please sign in to comment.