Ero nella stessa situazione, dopo tonnellate di ricerche, l'ho capito, la soluzione è usare @JsonView
e Spring che può iniettare uno ObjectMapper
nello JSON Writer senza uccidere la bellezza di Jersey.
Sto lavorando su un set di API REST, voglio ottenere un elenco di istanze di SystemObject
e il dettaglio un'istanza specifica di SystemObject
, proprio come te, voglio solo molto limitato del numero di proprietà di ogni istanza nel elenca alcune proprietà aggiuntive nei dettagli, definisco semplicemente le visualizzazioni per loro e aggiungo annotazioni nella classe SystemObject
. ma, per impostazione predefinita, tutte le proprietà senza annotazione @JsonView
verranno inviate a JSON, ma è disponibile una configurazione item(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION)
che posso utilizzare per escluderle.
Il problema è che devo impostarlo su true per soddisfare le mie esigenze. ma non posso cambiare l'ObjectMapper che fa la magia per convertire l'oggetto in JSON, leggendo i 3 articoli seguenti, ho avuto l'idea che l'unico modo che posso fare è iniettare un Modificato ObjectMapper
a Jersey. Ora ho quello che voglio.
È come se si creino più viste rispetto a una tabella di database.
Questi 3 link vi aiuterà in diversi modi:
How to create a ObjectMapperProvider which can be used by Spring to inject
Jersey, Jackson, Spring and JSON
Jersey + Spring integration example
risorsa RIPOSO:
package com.john.rest.resource;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.HeaderParam;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriInfo;
import org.codehaus.jackson.map.annotate.JsonView;
import org.springframework.stereotype.Component;
import com.midtronics.esp.common.EspException;
import com.midtronics.esp.common.SystemObject;
import com.midtronics.esp.mobile.model.SystemObjectView;
import com.midtronics.esp.model.accesscontrol.AccessControlBean;
import com.midtronics.esp.model.site.SiteBean;
@Component
@Path("/hierarchy")
public class Hierarchy {
// Allows to insert contextual objects into the class,
// e.g. ServletContext, Request, Response, UriInfo
@Context
UriInfo uriInfo;
@Context
Request request;
// Return the list of sites
@GET
@Path("sites")
@Produces(MediaType.APPLICATION_JSON)
@JsonView({SystemObjectView.ObjectList.class})
public List<SystemObject> listSite(
@HeaderParam("userId") String userId,
@HeaderParam("password") String password) {
ArrayList<SystemObject> sites= new ArrayList<SystemObject>();
try{
if(!AccessControlBean.CheckUser(userId, password)){
throw new WebApplicationException(401);
}
SystemObject.GetSiteListByPage(sites, 2, 3);
return sites;
} catch(EspException e){
throw new WebApplicationException(401);
} catch (Exception e) {
throw new WebApplicationException(500);
}
}
// Return the number of sites
@GET
@Path("sites/total")
@Produces(MediaType.TEXT_PLAIN)
public String getSiteNumber(@HeaderParam("userId") String userId,
@HeaderParam("password") String password) {
try{
return Integer.toString(SiteBean.GetSiteTotal());
} catch(EspException e){
throw new WebApplicationException(401);
} catch (Exception e) {
throw new WebApplicationException(500);
}
}
}
modello REST:
package com.john.rest.model;
import java.io.Serializable;
import java.util.ArrayList;
import javax.xml.bind.annotation.XmlRootElement;
import org.codehaus.jackson.annotate.JsonIgnore;
import org.codehaus.jackson.annotate.JsonProperty;
import org.codehaus.jackson.map.annotate.JsonView;
import com.midtronics.esp.mobile.model.SystemObjectView;
import com.midtronics.esp.model.common.ICommonDAO;
@XmlRootElement
public class SystemObject implements Serializable
{
private static final long serialVersionUID = 3989499187492868996L;
@JsonProperty("id")
@JsonView({SystemObjectView.ObjectList.class, SystemObjectView.ObjectDetail.class})
protected String objectID = "";
@JsonProperty("parentId")
protected String parentID = "";
@JsonProperty("name")
@JsonView({SystemObjectView.ObjectList.class, SystemObjectView.ObjectDetail.class})
protected String objectName = "";
//getters...
//setters...
}
REST vista del modello:
package com.john.rest.model;
public class SystemObjectView {
public static class ObjectList { };
public static class ObjectDetail extends ObjectList { }
}
Se potessi votare fino questa 20 volte lo farei. Fino a quando ho letto questo non avevo idea che si potesse applicare JsonView al metodo di risorsa Jersey per selezionare la vista da serializzare con. Se ciò è descritto nella documentazione, l'ho completamente perso. BTW - funziona senza Spring (sto usando Felix). Grazie mille! – sfitts
Non credo ci sia mancato questo nei documenti. Ho cercato un buon modo per farlo a lungo, e non l'ho mai trovato prima di aver visto questo post. –
Grazie alla segnalazione, il progetto README ora include una breve descrizione delle annotazioni applicabili agli endpoint JAX-RS - https://github.com/FasterXML/jackson-jaxrs-providers - e si spera che altri contenitori (Spring, Restlet) avere/aggiungere qualcosa di simile. – StaxMan