I have a domain javabean, some bean hvae a lot of information with password
and login Ip, I use the #jsonIgnore to filter that property which I dont
want the end user know.
But there has a problem,In other method
I use the same javabean to send back
to front side,but now I need some property from this domain
has anyway can cancel this #jsonIgnore in some specific method?
#JsonIgnore
private String address;
private Integer drawnum;
but now I need address , I cant do this.....
I dont want to use the for loop to add in other object.
I think that what you are looking for is the concept of JsonView : in some cases you want a set of attributes to be serialized, and in some other cases you want a (slightly) different set of attributes to be serialized.
Check this excellent tutorial, it explains evrything, even the use with Spring MVC.
Create classes to annotate the fields :
public class Views {
public static class Public {
}
public static class Internal extends Public {
}
}
Annotate the fields :
public class Item {
#JsonView(Views.Public.class)
public int id;
#JsonView(Views.Public.class)
public int drawnum;
#JsonView(Views.Internal.class)
public String address;
}
In the controller, if you want only "public" properties to be serialized ;
#JsonView(Views.Public.class)
#RequestMapping("/items/{id}")
public Item publicItem(#PathVariable int id) {
Result : {"id":2,"drawnum":5}
In another controller, if you want all properties to be serialized ;
#JsonView(Views.Internal.class)
#RequestMapping("/items/{id}")
public Item internalItem(#PathVariable int id) {
Result : {"id":2,"drawnum":5,"address":"My address"}
Related
Need some help here! I have a Java Rest API which is getting data from a .net endpoint and passing it on to the UI. The JSON properties are in capital case and I want to convert them in JAVA before sending it to the UI. Any pointers on this?
In java, I have a class like below:
public class Person {
#JsonProperty("Name")
private String name;
#JsonProperty("Age")
private int age;
}
I am using #JsonProperty as keys in .net are starting with capitalCase. How can I convert this back before sending it to the UI in Java?
Thanks for the help!
Create another class with the same structure and use there other names that you want. Something like this:
// Class to read .NET object
public class Person {
#JsonProperty("Name")
private String name;
#JsonProperty("Age")
private int age;
}
// Class to represent the object in Java REST API
public class Person {
#JsonProperty("name")
private String name;
#JsonProperty("age")
private int age;
}
// Class to represent the object in Java REST API,
// in case you use some standard library that
// uses property names for JSON as is
public class Person {
private String name;
private int age;
}
Of course you should put these classes into different packages.
Your code can look as follows:
xxx.dotnet.Person dotnetPerson = doSomethingViaDotNet(...);
yyy.rest.Person restPerson = new yyy.rest.Person();
restPerson.setName(dotnetPerson.getName());
restPerson.setAge(dotnetPerson.getAge());
...
return restPerson;
If you decide to use MapStruct, your code may looks as follows:
#Mapper
public interface PersonMapper {
PersonMapper INSTANCE = Mappers.getMapper( PersonMapper.class );
yyy.rest.Person dotnetToRest(xxx.dotnet.Person dotnetPerson);
}
Since all attributes have the same names and types you don't need anything else in your mapper.
MapStruct will generate a class that implements this interface. Usage will be as follows:
restPerson = PersonMapper.INSTANCE.dotnetToRest(dotnetPerson);
I have a model like this:
public class Employee {
#JsonProperty("emplyee_id")
private Integer id;
#JsonProperty("emplyee_first_name")
private String firstName;
#JsonProperty("emplyee_last_name")
private String lastName;
#JsonProperty("emplyee_address")
private String address;
#JsonProperty("emplyee_age")
private Byte age;
#JsonProperty("emplyee_level")
private Byte level;
//getters and setters
}
now I need to create two JSONs using this (only) model.
the first one must like this for example:
{
"employee_id":101,
"employee_first_name":"Alex",
"employee_last_name":"Light",
"employee_age":null,
"employee_address":null
}
and the second one must like this for example:
{
"employee_id":101,
"employee_level":5
}
by the way, I already tested #JsonIgnore and #JsonInclude(JsonInclude.Include.NON_NULL).
the problem of the first one (as much as I know) is, those fields can't be included in other JSONs (for example if level get this annotation, it won't be included in the second JSON)
and the problem of the second one is, null values can't be included in JSON.
so can I keep null values and prevent some other property to be included in JSON without creating extra models? if the answer is yes, so how can I do it? if it's not I really appreciate if anyone gives me the best solution for this state.
thanks very much.
it could be useful for you using #JsonView annotation
public class Views {
public static class Public {
}
public static class Base {
}
}
public class Employee {
#JsonProperty("emplyee_id")
#JsonView({View.Public.class,View.Base.class})
private Integer id;
#JsonProperty("emplyee_first_name")
#JsonView(View.Public.class)
private String firstName;
#JsonProperty("emplyee_last_name")
#JsonView(View.Public.class)
private String lastName;
#JsonProperty("emplyee_address")
private String address;
#JsonProperty("emplyee_age")
private Byte age;
#JsonProperty("emplyee_level")
#JsonView(View.Base.class)
private Byte level;
//getters and setters
}
in your json response add #JsonView(Public/Base.class) it will return based on jsonview annotations
//requestmapping
#JsonView(View.Public.class)
public ResponseEntity<Employee> getEmployeeWithPublicView(){
//do something
}
response:
{
"employee_id":101,
"employee_first_name":"Alex",
"employee_last_name":"Light",
"employee_age":null,
"employee_address":null
}
for the second one
//requestmapping
#JsonView(View.Base.class)
public ResponseEntity<Employee> getEmployeeWithBaseView(){
//do something
}
response
{
"employee_id":101,
"employee_level":5
}
I'm using neo4j + spring data. To access the data I'm using interfaces, that extends GraphRepository<E>. For example
public interface EntryRepository extends GraphRepository<Entry> {
#Query("start parent=node({0}), entry=node({1}) "
+ "match parent-[*1..2{removed:false}]->entry "
+ "return distinct entry")
Entry findOne(Long parentId, Long entryId);
}
I'm trying to get data, that differs from my domain models. My custom models looks like that
#QueryResult
public class EntryBean {
#ResultColumn("id")
private Long id;
#ResultColumn("name")
private String name;
#ResultColumn("content")
private String content;
...
//getters and setters
}
#QueryResult
public class BoardBean {
#ResultColumn("id")
private Long id;
#ResultColumn("name")
private String name;
...
//getters and setters
}
Obviously, that it will be better to separate duplicate fields to Base class and inherit from it. So, i'm doing next steps
#QueryResult
public class BaseBean {
#ResultColumn("id")
private Long id;
#ResultColumn("name")
private String name;
...
}
#QueryResult
public class EntryBean extends BaseBean{
#ResultColumn("content")
private String content;
...
//getters and setters
}
And I don't need BoardBean anymore. But when I'm trying run query
public interface EntryRepository extends GraphRepository<Entry> {
#Query("start user=node({0}), board=node({1}) "
+ "... "
+ "return id(entry) as id, entry.name as name, entry.content as content")
List<EntryBean> getRelatedEntries(Long userId, Long boardId);
}
I get filled by data just fields that directly declared into EntryBean class (i. e. "content" field).
So, How I can correctly implement the #QueryResult class hierarcy?
This is a bug which has been present for almost two years (even in 2.3.5.RELEASE!) in the class in charge of converting annotated POJOs.
Indeed, it calls getDeclaredFields on the most concrete type thus skipping possibly inherited annotated fields.
Before the issue is fixed, my piece of advice would be to tolerate this superficial field duplication on your side and not relying on inheritance for now.
I have the following class structure
public Abstract class Person {
private String fullName;
private Address address;
private Phone ;
}
class Staff extends Person{
private String staffId;
}
I want to apply validation using JSR-303 on class Staff whereby Staff address and phone cannot have the value of null. However, I have some other classes that are class of Person where I don't wish to have the validation to be applied.
One way to do this that I could think of is by refactor Person and push the fields 'address' and 'phone' to Staff, but this means refactoring a lot of other classes (and not to mention redundancy this shall cause), and hence something I want to avoid.
Update.
I have changed Staff class, as follows
public class Staff extends Person {
#NotNull
private String staffEmploymentId;
public String getStaffEmploymentId() {
return staffEmploymentId;
}
public void setStaffEmploymentId(String id) {
this.staffEmploymentId = id;
}
#Override
#NotNull
public void setPhones(List<Phone> phones) {
super.phones = phones;
}
#Override
#NotNull
public void setAddress(Address a) {
super.address = a;
}
#Override
#NotNull
public Address getAddress(){
return super.address;
}
}
However, I've got the following error.
javax.validation.ValidationException: Property setAddress does not follow javabean conventions.
I am using Apache BVal, as opposed to Hibernate Validator.
Annotate getters instead of fields using annotations from JSR-330.
You can override getters in Stuff and annotate them.
If I have two classes:
public class Person {
public String name;
public int age;
}
public class Address {
public String address;
public int number;
}
Should I construct a DTO like the following:
public class MyDTO {
public Person person;
public Address address;
}
or this:
public class MyDTO {
public String name;
public String address;
}
You can have whatever you want in a DTO, but the basic idea is to transport the smallest amount of data possible.
Remember though, that the purpose of a DTO is to transfer data around, quite possibly between JVM boundaries, for example when using EJBs. If this is the case, you must remember to make sure that all the classes that are referenced in your DTOs are serializable.
In the example you have above, the simplest DTO would be
public class MyDTO {
public String name;
public String address;
}
and could be easily consumed.
If your consumer is going to use a Person and Address class however, its probably easier to place them in the DTO so that they can be consumed easier.
There is no "one size fits all" answer. It depends on your environment and how you need to work.