Tengo clase de modelo como este, hibernate

@Entity
@Table(name = "user", catalog = "userdb")
@JsonIgnoreProperties(ignoreUnknown = true)
public class User implements java.io.Serializable {
private Integer userId;
private String userName;
private String emailId;
private String encryptedPwd;
private String createdBy;
private String updatedBy;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "UserId", unique = true, nullable = false)
public Integer getUserId() {
return this.userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
@Column(name = "UserName", length = 100)
public String getUserName() {
return this.userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
@Column(name = "EmailId", nullable = false, length = 45)
public String getEmailId() {
return this.emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
@Column(name = "EncryptedPwd", length = 100)
public String getEncryptedPwd() {
return this.encryptedPwd;
}
public void setEncryptedPwd(String encryptedPwd) {
this.encryptedPwd = encryptedPwd;
}
public void setCreatedBy(String createdBy) {
this.createdBy = createdBy;
}
@Column(name = "UpdatedBy", length = 100)
public String getUpdatedBy() {
return this.updatedBy;
}
public void setUpdatedBy(String updatedBy) {
this.updatedBy = updatedBy;
}
}

En la Primavera de controlador MVC, DAO, soy capaz de conseguir el objeto. y regresando como un Objeto JSON.

@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping(value = "/getUser/{userId}", method = RequestMethod.GET)
@ResponseBody
public User getUser(@PathVariable Integer userId) throws Exception {
User user = userService.get(userId);
user.setCreatedBy(null);
user.setUpdatedBy(null);
return user;
}
}

Ver la parte se hace uso de AngularJS, por lo que será JSON como este

{
"userId" :2,
"userName" : "john",
"emailId" : "[email protected]",
"encryptedPwd" : "Co7Fwd1fXYk=",
"createdBy" : null,
"updatedBy" : null
}

Si no desea establecer una Contraseña encriptada, voy a establecer que el campo también como null.

Pero yo no quiero, yo no quiero enviar todos los campos al lado del cliente. Si yo no quiero la contraseña, updatedby, createdby campos para enviar, Mi resultado JSON debe ser como

{
"userId" :2,
"userName" : "john",
"emailId" : "[email protected]"
}

La lista de campos que no quiero enviar a cliente procedentes de otra base de datos de la tabla. Así que va a cambiar en función del usuario que ha iniciado sesión. ¿Cómo puedo hacer eso?

Espero que Te tengo a mi pregunta.

InformationsquelleAutor iCode | 2014-04-16

14 Comentarios

  1. 112

    Agregar el @JsonIgnoreProperties("fieldname") anotación a su POJO.

    O puede utilizar @JsonIgnore antes de que el nombre del campo que desea ignorar mientras deserializar JSON. Ejemplo:

    @JsonIgnore
    @JsonProperty(value = "user_password")
    public java.lang.String getUserPassword() {
    return userPassword;
    }

    GitHub ejemplo

    • Puedo hacerlo de forma dinámica? No en POJO? Puedo hacerlo en mi clase de Controlador?
    • aquí está una similar como desee :stackoverflow.com/questions/8179986/…
    • muy impresionante respuesta aquí stackoverflow.com/questions/13764280/…
    • comentario:@JsonIgnore es com.fasterxml.jackson.annotation.JsonIgnore no org.codehaus.jackson.annotate.JsonIgnore.
    • Que ignora tanto, mientras que la lectura de la solicitud y mientras que el envío de la respuesta. Quiero ignorar, mientras que sólo el envío de la respuesta porque necesito que la propiedad del objeto de petición. Alguna idea?
    • Hola @zulkarnainshah: usted puede usar json serializador de entonces.
    • Yo creo que es necesario establecer el JSONIgnore en el método getter de ese campo y eliminarlo desde el propio campo.
    • consulte stackoverflow.com/questions/12505141/… para obtener más detalles
    • Ya el JSONIgnore debe ser sólo en la parte superior del método getter. Gracias !
    • Supongo que JsonFilter anotación es lo que usted necesita.

  2. 26

    Sé que soy un poco tarde a la fiesta, pero en realidad me encontré con este, así como un par de meses. Todas las soluciones no eran muy atractivo para mí (mixins? ugh!), así que terminé la creación de una nueva biblioteca para hacer este proceso más limpio. Está disponible aquí si alguien quiere probarlo: https://github.com/monitorjbl/spring-json-view.

    El uso básico es bastante simple, se utiliza la JsonView objeto en el controlador de métodos como:

    import com.monitorjbl.json.JsonView;
    import static com.monitorjbl.json.Match.match;
    @RequestMapping(method = RequestMethod.GET, value = "/myObject")
    @ResponseBody
    public void getMyObjects() {
    //get a list of the objects
    List<MyObject> list = myObjectService.list();
    //exclude expensive field
    JsonView.with(list).onClass(MyObject.class, match().exclude("contains"));
    }

    También se puede utilizar fuera de la Primavera:

    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.fasterxml.jackson.databind.module.SimpleModule;
    import static com.monitorjbl.json.Match.match;
    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addSerializer(JsonView.class, new JsonViewSerializer());
    mapper.registerModule(module);
    mapper.writeValueAsString(JsonView.with(list)
    .onClass(MyObject.class, match()
    .exclude("contains"))
    .onClass(MySmallObject.class, match()
    .exclude("id"));
    • Gracias! Este era el camino a seguir para mí. Necesitaba personalizado JSON puntos de vista con los mismos objetos en diferentes lugares y @JsonIgnore sólo no iba a funcionar. Esta biblioteca hizo muertos simple de hacer.
    • Usted ha hecho mi código más limpio y de aplicación más fácil. gracias
    • esto es un poco fuera de pista, he utilizado json vistas y su solución de mi propósito. Pero yo no soy capaz de registrar serializador personalizado para java.util.Fecha de la clase(no en tiempo de ejecución/error de tiempo de compilación) fueron para la cadena que fue capaz de registrar serializador personalizado.
  3. 9

    Agregar @JsonInclude(JsonInclude.Include.NON_NULL) (fuerzas de Jackson para serializar los valores nulos) para la clase así como @JsonIgnore al campo de contraseña.

    Usted podría, por supuesto, establecer @JsonIgnore en createdBy y updatedBy así que si usted siempre quiere ignorar a continuación, y no sólo en este caso específico.

    ACTUALIZACIÓN

    En el caso de que usted no desea agregar la anotación a la POJO sí mismo, una gran opción es Jackson Mixin Anotaciones. Retirar el documentación

    • Puedo hacerlo de forma dinámica? No en POJO? Puedo hacerlo en mi clase de Controlador?
    • ¿Quiere usted decir que usted no desea agregar anotaciones a la POJO?
    • Porque a Veces yo quiera enviar todos los campos al lado del cliente. A veces algunos de los campos. Los campos donde debo enviar a lado del cliente es la de sacar de la base de datos en el controlador sólo en la clase. Después de eso sólo tengo que definir qué campos deben ignorar.
    • Echa un vistazo a mi respuesta actualizada
  4. 7

    Sí, usted puede especificar qué campos se serializa como respuesta JSON y cuáles ignorar.
    Esto es lo que usted necesita hacer para implementar de forma Dinámica ignorar propiedades.

    1) en Primer lugar, usted necesita para agregar @JsonFilter de com.fasterxml.jackson.la anotación.JsonFilter en su clase de entidad como.

    import com.fasterxml.jackson.annotation.JsonFilter;
    @JsonFilter("SomeBeanFilter")
    public class SomeBean {
    private String field1;
    private String field2;
    private String field3;
    //getters/setters
    }

    2), a Continuación, en el controlador, se debe agregar crear el MappingJacksonValue objeto y establecer filtros y en el extremo, usted tiene que devolver este objeto.

    import java.util.Arrays;
    import java.util.List;
    import org.springframework.http.converter.json.MappingJacksonValue;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    import com.fasterxml.jackson.databind.ser.FilterProvider;
    import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter;
    import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider;
    @RestController
    public class FilteringController {
    //Here i want to ignore all properties except field1,field2.
    @GetMapping("/ignoreProperties")
    public MappingJacksonValue retrieveSomeBean() {
    SomeBean someBean = new SomeBean("value1", "value2", "value3");
    SimpleBeanPropertyFilter filter = SimpleBeanPropertyFilter.filterOutAllExcept("field1", "field2");
    FilterProvider filters = new SimpleFilterProvider().addFilter("SomeBeanFilter", filter);
    MappingJacksonValue mapping = new MappingJacksonValue(someBean);
    mapping.setFilters(filters);
    return mapping;
    }
    }

    Esto es lo que usted conseguirá en respuesta:

    {
    field1:"value1",
    field2:"value2"
    }

    lugar de este:

    {
    field1:"value1",
    field2:"value2",
    field3:"value3"
    }

    Aquí puedes ver ignora otras propiedades(campo3 en este caso) en respuesta excepto para los bienes campo1 y campo2.

    Espero que esto ayude.

    • Esto no funciona para mí.
    • Hombre, muchas gracias, eres mi salvador. Pasó casi un día tratando de encontrar este tipo de funcionalidad. Esta solución es tan elegante y simple? y hace exactamente lo que se le pidió. Debe marcar la respuesta correcta.
  5. 5

    Si yo fuera usted, y quería hacerlo, yo no lo uso mi entidad Usuario en la capa del Controlador.En lugar de eso crear y utilizar UserDto (transferencia de Datos de objeto) para comunicarse con los negocios(Servicio) de la capa y el Controlador.
    Usted puede utilizar Apache ConvertUtils para copiar datos de la entidad de Usuario para UserDto.

  6. 4

    Puedo hacerlo de forma dinámica?

    Crear vista de la clase:

    public class View {
    static class Public { }
    static class ExtendedPublic extends Public { }
    static class Internal extends ExtendedPublic { }
    }

    Anotar que el modelo de

    @Document
    public class User {
    @Id
    @JsonView(View.Public.class)
    private String id;
    @JsonView(View.Internal.class)
    private String email;
    @JsonView(View.Public.class)
    private String name;
    @JsonView(View.Public.class)
    private Instant createdAt = Instant.now();
    //getters/setters
    }

    Especificar la clase de vista en el controlador

    @RequestMapping("/user/{email}")
    public class UserController {
    private final UserRepository userRepository;
    @Autowired
    UserController(UserRepository userRepository) {
    this.userRepository = userRepository;
    }
    @RequestMapping(method = RequestMethod.GET)
    @JsonView(View.Internal.class)
    public @ResponseBody Optional<User> get(@PathVariable String email) {
    return userRepository.findByEmail(email);
    }
    }

    De datos ejemplo:

    {"id":"5aa2496df863482dc4da2067","name":"test","createdAt":"2018-03-10T09:35:31.050353800Z"}
    • Esta es una fantástica y minimalista respuesta! Yo quería volver como un JSON sólo algunos de los campos de un @de Configuración anotado componente y saltarse todos los internos de los campos que se incluyen automáticamente. Muchas gracias!
  7. 4

    Podemos hacerlo mediante la configuración de acceso a JsonProperty.Access.WRITE_ONLY, al declarar la propiedad.

    @JsonProperty( value = "password", access = JsonProperty.Access.WRITE_ONLY)
    @SerializedName("password")
    private String password;
    • Gracias, tu respuesta resuelto mi problema!
    • saludos @EliasMeireles !
  8. 1

    He encontrado una solución para mí la Primavera y jackson

    Especificar en primer lugar el nombre del filtro en la entidad

    @Entity
    @Table(name = "SECTEUR")
    @JsonFilter(ModelJsonFilters.SECTEUR_FILTER)
    public class Secteur implements Serializable {
    /** Serial UID */
    private static final long serialVersionUID = 5697181222899184767L;
    /**
    * Unique ID
    */
    @Id
    @JsonView(View.SecteurWithoutChildrens.class)
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;
    @JsonView(View.SecteurWithoutChildrens.class)
    @Column(name = "code", nullable = false, length = 35)
    private String code;
    /**
    * Identifiant du secteur parent
    */
    @JsonView(View.SecteurWithoutChildrens.class)
    @Column(name = "id_parent")
    private Long idParent;
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_parent")
    private List<Secteur> secteursEnfants = new ArrayList<>(0);
    }

    Entonces usted puede ver las constantes de filtros de nombres de clase con el defecto de FilterProvider utilizado en la primavera de configuración

    public class ModelJsonFilters {
    public final static String SECTEUR_FILTER = "SecteurFilter";
    public final static String APPLICATION_FILTER = "ApplicationFilter";
    public final static String SERVICE_FILTER = "ServiceFilter";
    public final static String UTILISATEUR_FILTER = "UtilisateurFilter";
    public static SimpleFilterProvider getDefaultFilters() {
    SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter.serializeAll();
    return new SimpleFilterProvider().setDefaultFilter(theFilter);
    }
    }

    Primavera de configuración :

    @EnableWebMvc
    @Configuration
    @ComponentScan(basePackages = "fr.sodebo")
    public class ApiRootConfiguration extends WebMvcConfigurerAdapter {
    @Autowired
    private EntityManagerFactory entityManagerFactory;
    /**
    * config qui permet d'éviter les "Lazy loading Error" au moment de la
    * conversion json par jackson pour les retours des services REST<br>
    * on permet à jackson d'acceder à sessionFactory pour charger ce dont il a
    * besoin
    */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    super.configureMessageConverters(converters);
    MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
    ObjectMapper mapper = new ObjectMapper();
    //config d'hibernate pour la conversion json
    mapper.registerModule(getConfiguredHibernateModule());//
    //inscrit les filtres json
    subscribeFiltersInMapper(mapper);
    //config du comportement de json views
    mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, false);
    converter.setObjectMapper(mapper);
    converters.add(converter);
    }
    /**
    * config d'hibernate pour la conversion json
    * 
    * @return Hibernate5Module
    */
    private Hibernate5Module getConfiguredHibernateModule() {
    SessionFactory sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
    Hibernate5Module module = new Hibernate5Module(sessionFactory);
    module.configure(Hibernate5Module.Feature.FORCE_LAZY_LOADING, true);
    return module;
    }
    /**
    * inscrit les filtres json
    * 
    * @param mapper
    */
    private void subscribeFiltersInMapper(ObjectMapper mapper) {
    mapper.setFilterProvider(ModelJsonFilters.getDefaultFilters());
    }
    }

    Endly puedo especificar un filtro específico en restConstoller cuando la necesito….

    @RequestMapping(value = "/{id}/droits/", method = RequestMethod.GET)
    public MappingJacksonValue getListDroits(@PathVariable long id) {
    LOGGER.debug("Get all droits of user with id {}", id);
    List<Droit> droits = utilisateurService.findDroitsDeUtilisateur(id);
    MappingJacksonValue value;
    UtilisateurWithSecteurs utilisateurWithSecteurs = droitsUtilisateur.fillLists(droits).get(id);
    value = new MappingJacksonValue(utilisateurWithSecteurs);
    FilterProvider filters = ModelJsonFilters.getDefaultFilters().addFilter(ModelJsonFilters.SECTEUR_FILTER, SimpleBeanPropertyFilter.serializeAllExcept("secteursEnfants")).addFilter(ModelJsonFilters.APPLICATION_FILTER,
    SimpleBeanPropertyFilter.serializeAllExcept("services"));
    value.setFilters(filters);
    return value;
    }
    • por qué complicaciones para una pregunta fácil
  9. 1

    He creado un JsonUtil que puede ser utilizado para ignorar los campos en tiempo de ejecución, mientras que dar una respuesta.

    Ejemplo De Uso :
    Primer argumento debe ser cualquier clase POJO (Estudiante) y ignoreFields es por comas separan los campos que desea ignorar la respuesta.

     Student st = new Student();
    createJsonIgnoreFields(st,"firstname,age");
    import java.util.logging.Logger;
    import org.codehaus.jackson.map.ObjectMapper;
    import org.codehaus.jackson.map.ObjectWriter;
    import org.codehaus.jackson.map.ser.FilterProvider;
    import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter;
    import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider;
    public class JsonUtil {
    public static String createJsonIgnoreFields(Object object, String ignoreFields) {
    try {
    ObjectMapper mapper = new ObjectMapper();
    mapper.getSerializationConfig().addMixInAnnotations(Object.class, JsonPropertyFilterMixIn.class);
    String[] ignoreFieldsArray = ignoreFields.split(",");
    FilterProvider filters = new SimpleFilterProvider()
    .addFilter("filter properties by field names",
    SimpleBeanPropertyFilter.serializeAllExcept(ignoreFieldsArray));
    ObjectWriter writer = mapper.writer().withFilters(filters);
    return writer.writeValueAsString(object);
    } catch (Exception e) {
    //handle exception here
    }
    return "";
    }
    public static String createJson(Object object) {
    try {
    ObjectMapper mapper = new ObjectMapper();
    ObjectWriter writer = mapper.writer().withDefaultPrettyPrinter();
    return writer.writeValueAsString(object);
    }catch (Exception e) {
    //handle exception here
    }
    return "";
    }
    }    
  10. 1

    He resuelto utilizando sólo @JsonIgnore como @kryger ha sugerido.
    Por lo que su getter será:

    @JsonIgnore
    public String getEncryptedPwd() {
    return this.encryptedPwd;
    }

    Puede establecer @JsonIgnore, por supuesto, en el campo, setter o captador, como se describe aquí.

    Y, si desea proteger la contraseña cifrada sólo en la serialización de lado (por ejemplo, cuando necesitas acceder a tu usuarios), agregar este @JsonProperty anotación a su campo:

    @JsonProperty(access = Access.WRITE_ONLY)
    private String encryptedPwd;

    Más info aquí.

  11. 0

    No sería la creación de un UserJsonResponse clase y rellenar con la que quería campos de ser una solución de limpieza?

    Regresar directamente un JSON parece una gran solución cuando se desea dar a todos el modelo de la espalda. De lo contrario, simplemente se hace un desorden.

    En el futuro, por ejemplo, es posible que desee tener un campo de JSON que no coincida con ningún Modelo de campo y, a continuación, usted está en un problema más grande.

  12. 0

    Esta es una buena herramienta de utilidad para el de arriba respuesta :

    @GetMapping(value = "/my-url")
    public @ResponseBody
    MappingJacksonValue getMyBean() {
    List<MyBean> myBeans = Service.findAll();
    MappingJacksonValue mappingValue = MappingFilterUtils.applyFilter(myBeans, MappingFilterUtils.JsonFilterMode.EXCLUDE_FIELD_MODE, "MyFilterName", "myBiggerObject.mySmallerObject.mySmallestObject");
    return mappingValue;
    }
    //AND THE UTILITY CLASS
    public class MappingFilterUtils {
    public enum JsonFilterMode {
    INCLUDE_FIELD_MODE, EXCLUDE_FIELD_MODE
    }
    public static MappingJacksonValue applyFilter(Object object, final JsonFilterMode mode, final String filterName, final String... fields) {
    if (fields == null || fields.length == 0) {
    throw new IllegalArgumentException("You should pass at least one field");
    }
    return applyFilter(object, mode, filterName, new HashSet<>(Arrays.asList(fields)));
    }
    public static MappingJacksonValue applyFilter(Object object, final JsonFilterMode mode, final String filterName, final Set<String> fields) {
    if (fields == null || fields.isEmpty()) {
    throw new IllegalArgumentException("You should pass at least one field");
    }
    SimpleBeanPropertyFilter filter = null;
    switch (mode) {
    case EXCLUDE_FIELD_MODE:
    filter = SimpleBeanPropertyFilter.serializeAllExcept(fields);
    break;
    case INCLUDE_FIELD_MODE:
    filter = SimpleBeanPropertyFilter.filterOutAllExcept(fields);
    break;
    }
    FilterProvider filters = new SimpleFilterProvider().addFilter(filterName, filter);
    MappingJacksonValue mapping = new MappingJacksonValue(object);
    mapping.setFilters(filters);
    return mapping;
    }
    }
  13. 0

    Lugar @JsonIgnore en el campo o su getter, o crear una personalizada dto

    @JsonIgnore
    private String encryptedPwd;

    o como se mencionó anteriormente por ceekay anotar con @JsonProperty donde el acceso se establece el atributo de sólo escritura

    @JsonProperty( value = "password", access = JsonProperty.Access.WRITE_ONLY)
    private String encryptedPwd;
  14. -4

    En su clase de entidad agregar @JsonInclude(JsonInclude.Include.NON_NULL) anotación para resolver el problema

    se verá como

    @Entity
    @JsonInclude(JsonInclude.Include.NON_NULL)
    • Totalmente ya irrelevante respondió. El objetivo de la pregunta es diferente, mientras que la respuesta es algo más. -1 para que

Dejar respuesta

Please enter your comment!
Please enter your name here