Reputation: 7255
I am looking for a dynamic way to control the response object coming back from a request using query params.
I am using Jersey 2.x and Hibernate 4 for managing entities along with some Spring sprinkles for security etc.The problem is that Jersey is not serializing the attached entity but only the base entity. I am currently using the com.fasterxml.jackson.datatype.hibernate4
. that gives me some of the flexiblity to handle how to load child and parent entities using JPA fetch=Eager etc. However I really want to make this dynamic.
I tried a simple dynamic loading by specifying a ?with=<someentity>
to specify what entities to attach. When fetching the entity I use reflection to call the getter for someentity and it attaches the entity successfully but when sending the entity out it is not serializing the attached entity.
Here is a super simple example of what I am trying to do. This is really just a piece parted together but the idea is there. The problem is when I get the Campaign object back form the server it is not serializing the entities that are attached by calling loadEntity.
@Path("campaign")
public class CampaignResource {
@GET
@Path("{entity_id}")
public Campaign find(@PathParam("entity_id") final Long id, @QueryParam("with") final String with) {
T entity = repository.findOne(id);
load(entity, with);
return entity;
}
/**
* This is used to attach entities that are requested via the api.
*
* @param entity
* @param with
*/
@SuppressWarnings("unused")
protected void loadWithEntities(T entity, final String with) {
String[] withFields;
if (with.contains(",")) {
// Split the with clause into separate values
withFields = with.split(",");
} else {
// Single with clause
withFields = new String[] { with };
}
for (String field : withFields) {
final String getterMethodName = getMethodGetterForField(field);
Method method = null;
try {
method = entityClass.getMethod(getterMethodName);
if (method != null) {
logger.info("Loading entity " + getterMethodName);
// Some odd reason we have to assign the variable so that it
// is attached.
final Object attached = method.invoke(entity);
}
} catch (Exception e) {
logger.error("Unable to find method name %s ", getterMethodName, e);
}
}
}
}
Upvotes: 1
Views: 559
Reputation: 208994
Jersey has the Entity Data Filtering to handle this use case. Hopefully you are using a later version of Jersey, as Jackson is not supported until (somewhere between 2.14 :-) and 2.16. Too lazy to check when. I'm guessing you are using the jersey-media-json-jackson
. You will know if you version is supported if it pulls in the jersey-entity-filtering
dependency. You don't need to add anything else.
You only need to configure three thing:
SelectableEntityFilteringFeature
.Configure the query parameter name.
.property(SelectableEntityFilteringFeature.QUERY_PARAM_NAME, "with")
There are different types of filtering features, but here is the section on query param filtering. There's not much information, because well, there's not much information to tell. All you really need to know is how to configure, and it work as you expect, i.e. ?with=prop1,prop2,prop3
Upvotes: 1