I am using Spring web services REST API that gives the JSON response.
The API usage:
#ResponseBody
#RequestMapping(value="/user", method = {RequestMethod.POST})
Details user(#RequestParam("username")
String username, #RequestParam("password") String password)
The JSON coming is:
{
"result":{
"details" : {
"firstName":"My",
"lastName":"God",
"enabled": false,
"id":927878192,
"language":"en_US",
}
}
}
I am having a Details class with the getter and setter methods for firstName, lastName, enabled, id and language.
The class is annotated with #JsonIgnoreProperties(ignoreUnknown = true).
However I don't want to show language and enabled in JSON response.
So in my java code, I did the following for language:
details.setLanguage(null);
That worked fine.
But I can't do details.setEnabled(null) because the enabled variable is primitive that can take true or false but not null. So my JSON response always has "enabled": false.
What can be done so that this field will not be a part of JSON response.
Try to use #JsonIgnore annotation on field level.
For example:
#JsonIgnore
private boolean isActive;
If you want to ignore the property only for selected response I suggest using #JsonView from com.fasterxml.jackson.annotation package but it could be an overkill.
First you need to create a class with an interface inside:
public class View {
public interface UserDetailed {}
}
After that you specify in your class which field should be visible only for specific 'profile':
public class User {
// Other fields
#JsonView(View.UserDetailed.class)
private List<Role> roleCollection = new ArrayList<Role>();
// Other fields, getters and setters
}
Then on the controller's method that needs to display that property you do:
#Controller
public class UserController{
#RequestMapping(value = "/userWithRoles", method = RequestMethod.GET)
#JsonView(View.UserDetailed.class)
public User getUserWithRoles() {…}
#RequestMapping(value = "/userWithoutRoles", method = RequestMethod.GET)
public User getUserWithoutRoles() {…}
}
The result is: only the controller methods that have the same #JsonView as the field will display it. Other will ignore it. It allows you to manage the visibility of the fields depending on the use case.
Here you can read more about it:
http://wiki.fasterxml.com/JacksonJsonViews
Put #JsonIgnore on the enabled getter method.
If you want to ignore it only during serialization but you need it when deserializing (if you need to edit that field from some method of the REST API), you can annotate with #JsonSetter("enabled") the enabled setter method.
Example:
public class Details {
....
private boolean enabled;
...
#JsonIgnore
public boolean isEnabled()
#JsonSetter
public void setEnabled(boolean enabled)
}
If you for some API method need enabled and for others no, the cleanest way to do so is to have two DTOs:
public class DetailsBasic {
private String firstName;
private String lastName;
private long id;
// getters and setters
}
public class Details extends DetailsBasic {
private boolean enabled;
private boolean language;
// getters and setters
}
And then in your controller:
#ResponseBody
#RequestMapping(value="/user", method = {RequestMethod.POST})
DetailsBasic user(#RequestParam("username")
String username, #RequestParam("password") String password) {
return ...
}
#ResponseBody
#RequestMapping(value="/otherMethod", method = {RequestMethod.POST})
Details otherMethod(#RequestParam("username")
String username, #RequestParam("password") String password) {
return ...
}
Related
I have a REST service that takes an object containing an enum field as input. When a value not present in the enum is passed to me in input, a BAD REQUEST is automatically launched. I tried to go into debug to see where to handle the error but I notice that it doesn't really enter the method.
Retrieve interface:
#POST
#Path("/retrieve")
public Response retrieveValue(#Valid User user);
User:
public class User(){
String name;
String surname;
CityEnum city;
// getter and setter whith #NotNull annotation
}
CityEnum:
public enum CityEnum(){
LONDON("London"),
LIVERPOOL("Liverpool"),
...
private String city;
}
I need to return an error message and I assume the handling will be done in the RetrieveService which implements the Retrieve interface. How can this be done?
I am using Mricroprofile.
We have SpringBoot application.
For our pojo's we want to create a custom #ToLowerCase annotation which converts the field variable value to lower case.
Eg:
#Data
Employee {
private String name;
#ToLowerCase
private String emailId;
private String gender;
private String phoneNumber;
}
So my custom #ToLowerCase annotation should convert emailId to lower case.
We want to use this annotation on all kind of Pojos, whether it is rest request pojo or JPA entity pojo.
I have gone through posts on many forums but didn't get any appropriate solution for same.
Is it possible to create such annotation in Spring Boot? If yes then how?
Kindly help
Thanks
Create a custom converter: ToLowerCaseConverter.
public class ToLowerCaseConverter extends StdConverter<String, String> {
#Override
public String convert(String value) {
if (value == null){
return null;
}
return value.toLowerCase();
}
}
After create a new annotation: ToLowerCase. It works for both incoming and outgoing Strings (#JsonDeserialize/#JsonSerialize).
#Retention(RetentionPolicy.RUNTIME)
#JacksonAnnotationsInside
#JsonSerialize(converter = ToLowerCaseConverter.class)
#JsonDeserialize(converter = ToLowerCaseConverter.class)
public #interface ToLowerCase {
}
Finally, your example will work as intended:
#Data
Employee {
#ToLowerCase
private String emailId;
}
first of all,i am fairly new with spring mvc so ..
how springmvc find the right class to instantiate and fill its object properties when sending post-request to some controller.
for example lets assume i have this class
package springmvc_test.user
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
and controller class as the flowing
#Controller
#RequestMapping(value = {"/user"} )
public class UserController {
private List<User> users;
#Autowired
public UserController(List<User> users) {
this.users = users;
}
#RequestMapping(value = "/add",method = POST)
public String addUser(User user,Model m){
users.add(user);
//do some other stuf
//.....
}
}
when i do post-request for http://localhost/myapp/user/add
along with form fields that has the same names as User class properties,
it works fine.
but my question is that
how could springmvc find the User class and instantiated it ?although the User class is not annotated with noting at all
note:
i know that spring binds the User object properties by matching their names with form fields names
As the Spring Framework reference states in the respective section you should use either:
#RequestBody, if you want to let a HttpMessageConverter deserialize your HTTP request to any Java Object
#ModelAttribute if you want to get access to model variables, e.g. also out of your HTTP request.
on the parameter which you want to associate with your request data.
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"}
I am rookie in Java Annotation and have been searching for applying single annotation on multiple variable simultaneously.
Code:
#Document(collection = "users")
public class User {
private ObjectId id;
#NotNull
private String email;
private String imageURL;
private String authToken;
private Date createdDate;
private Date updateDate;
private boolean isActivated;
private int credits;
.....getter/Setter Method
I want to apply #NotNull property on email, imageURL and authToken too. I can do it by writing #NotNull to each variable but not preferring. How to do it?
#NotNull annotation can be applied at element not at group of elements.
JavaDoc: The annotated element must not be null. Accepts any type.
If you really want to get away with boiler plate code, you can use frameworks like Lombok which can help you to certain extent.
Link : http://projectlombok.org/features/Data.html
OR you can use reflection to validate all the method.
for (Field f : obj.getClass().getDeclaredFields()) {
f.setAccessible(true); // optional
if (f.get(obj) == null) {
f.set(obj, getDefaultValueForType(f.getType()));
// OR throw error
}
}
Java does not support multiple annotation of this type. But you can write something like this
Create a class with annotated field.
Create setters and getters to access the field.
Create all your name,email field as instance of this class.
This way fields will implicitly annotated as NotNull.
public class NotNullString {
#NotNull
String str;
public void set(String str)
{
this.str = str;
}
public String get()
{
return this.str;
}
}
NotNullString name;
NotNullString email;