hasErrors(): how to ignoring validation of specific input - java

I have a User class with many variables (name, email, password, etc) and sometimes I need to update only one or two of them (using a form). I get the data from the form and use bind of a json object:
Form<User> userForm = User.form.bind(json);
if(userForm.hasErrors()) {
return badRequest("error");
}
hasError() retrieves error because it doesn't receive some data. How can I tell to hasError() that it have not to validate some specific fields?

Take a look at the "Forms" sample app on GitHub. It shows how to assign a "group" to your constraints such that you can enforce a different set of constraints depending on the situation. The projects I'v worked on are still on Play 2.0.x which didn't have this, but I believe it is in Play 2.1 and/or 2.2.
https://github.com/playframework/playframework/tree/master/samples/java/forms
The files you want to look at are the User model and Wizard controller.
app/models/User.java
In your model you assign constraints to specific groups. The groups seem to just be interfaces defined within the model class.
#Required(groups = {All.class, Step1.class})
#MinLength(value = 4, groups = {All.class, Step1.class})
public String username;
app/controllers/Wizard.java
Now when you do your form binding you pass in the group/interface class that you want to validate.
Form<User> filledForm = form(User.class, User.Step1.class).bindFromRequest();

Related

Ignore fields from being passed on in Json Object

I have a POJO called User which is also being used for inserting documents in MongoDb.
#Data
#Document(collection = Constants.COLLECTION_USERS)
public class User {
public ObjectId _id;
public String userID;
public String email;
public String name;
public String sex;
public String dob;
public String photo;
//have more variables
}
I have a simple application where a user registers by giving in a subset of data listed in the User class. The signature of the register method in my controller is as follows.
public GenericResponse registerUser(#RequestBody User userRegistrationRequest)
It can be noticed that I am using the same POJO for the registration request. Until now everything is fine. I can persist the data user object just fine.
This registration API is just used to persist a small set of a user's data. There would be other information as well in the MongoDb document, which would be accessed/persisted from some other APIs.
Suppose a user has registered with the basic information and also has persisted other information via APIs other than the registration one.
How would I make an API which can just get me some selective data from the User document again using the same User Pojo? If I call the repository to give data for a specific userID, it will give me the whole document mapped to the User class. I don't want my API to give all the information stored in the document.
One approach is to make another POJO with the details I want, and map the information selectively using a Converter. But, I want to avoid this approach, as I want to use the same class.
Second approach: Modify the Mongo query to return data selectively as given in the docs. But here I would have to specify all the fields I want in the result set. This would again be a length query.
Is there a better way to filter out data from the object?
How would I make an API which can just get me some selective data from the User document again using the same User Pojo?
How would I go off-road with a car I would like to take me girl to the restaurant at the evening? I would not - if I would have the same car for everything I would look stupid next to the restaurant, coming out in a suite or I would stuck in a swamp.
The biggest Java advantage is object creation time - you should not be afraid of it. Just create another model for registration, another as DTO for saving data, another for front-end presentation etc
Never mix responsibility of objects. You will finish with something like
#Entity
class ThePileOfShit {
#Id
private Long id;
#my.audit.framework.Id
private String anotherId;
#JsonIgnore
// just a front-end flag ignore
private boolean flag;
#Column
// not a field but getter because of any-weird-issue-you-want-to-put-here
public String getWeirdStuff() { ... }
// Useless converters
public ModelA getAsModelA() { ... }
public ModelB getAsModelB() { ... }
// etc
// etc
}
Four frameworks, five technologies - nobody knows what's going on.
If you are afraid of converting stuff use ModelMapper or another tool but keep your POJOs as simple as possible
You can use Gson's #Expose annotation only on the fields you want to return in the API.
To serialize the data, use:
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String json = gson.toJson(userData);

Hiding sensitive information in response

I am currently working in a project where I have a User model and am using a REST API to fetch a list of users. (I have more entities.)
User has a password field. I do not want to include the password field in the result. So I excluded it in the DTO. But when I want to create a User, I want to include the password in the request. So Spring MVC gets the User entity (not the DTO).
I don't think it is good to do so.... For example, I have Event model which is connected to user with a many-to-many relationship. I don't want that in the request. I want only the user. So what do you suggest me to do? Have another kind-of DTO?
Use #JsonIgnore with Access.WRITE_ONLY for getter methods only.
Example
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String password;
If you are using Jackson to serialize your response objects, you can annotate the property in question with #JsonIgnore and it will not be included in the response.
public User {
private String email;
#JsonIgnore
private String password
...getters and setters
}
It might also be a good idea to create separate response objects that only include the fields you want in case you add sensitive fields down the road and forget to hide them. Likewise, you would also have separate request objects for creating users that would include a password field. Business entities, like a User, are probably best to use only internally, so you can control what information goes public.
To avoid using #JsonIgnore, you can use json-view library.
For example, in your controller you can do something like this:
At first, declare this in your controller variable:
private JsonResult json = JsonResult.instance();
And then use this method:
#RequestMapping("/get/{id}")
public void getUserById(#PathVariable(value = "id") long id) {
User user = usersService.findOne(id);
json.use(JsonView.with(user)
.onClass(User.class, Match.match()
.exclude("password").exclude("yetAnothertopSecretField")));
}
It returns JSON without excluded fields.
The JsonView and JsonResult classes are imported from the json-view library.
I'm tried this JsonProperty.Access.WRITE_ONLY and it's working with me.
#JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
Make the field 'password' as null while sending the response and Jackson will not show that in response. Don't remove it completely from the model class.

Is Spring Data Mongodb, how can I reference one document from another without going via IDs

I'm using MongoDB with Spring Data. I'd like to have one document reference another (a user in fact), but I end up with having to do extra work. E.g.
class Watch {
String id;
User user;
}
That's nice, but I seem to end up with the whole user embedded in the document, so I do this:
class Watch {
String id;
String userId;
}
But then I want to use it in some JSTL, and I want to do this:
${watch.user.email}
But I have to add some mapping code.
Use #DBRef annotation on user.
You need to save user separately (no cascading), but you probably want to do that.
Beware that user will be loaded eagerly.

Have different names in class field and bound form input with Spring forms?

Does anyone know if it is possible, using automatic Spring databinding with tags, to have the form name be different from the class/object field it is bound to?
I am working on a system where, by convention, parameters passed through GET and POST have a prefix. That prefix doesn't jibe all that well with Java conventions as to class and field names.
Hibernate, for instance, allows custom naming of tables and columns that hold object data.
Is there something similar, an annotation perhaps, that works this way for forms?
I'm thinking of something like this:
#FormInputName(value = "pre_firstName") private String firstName;
And then in my JSP:
<form:input path="pre_firstName"/>
You can use #RequestParam(value="form_field_name") like this:
#RequestParam(value = "pre_firstName") private String firstName;
http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/bind/annotation/RequestParam.html

Submitting / binding partial objects with spring mvc

The Spring MVC binding mechanism is powerful, but I'm now confronted with a trivial issue that I wonder how to resolve:
User JPA entity, that is used for the binding and validation as well (i.e. throughout all layers)
"Edit profile" page, that is not supposed to change the password or some other entity properties
Two ways that I can think of:
Using the same object
use #InitBinder to configure a list of disallowed properties
obtain the target user (by id)
then use a reflection utility (BeanUtils) to copy the submitted object to the target object, but ignore null values - i.e. fields that are not submitted
Introduce a new object that has the needed subset of fields, and use BeanUtils.copyProperties(..) to merge it to the entity.
Alternatives?
I've found that as soon as your web model starts to diverge from your business layer in function, it's best to use a view layer object (a model object) to collect, or display the data
the entity:
public class com.myapp.domain.UserEntity {
}
the model object:
public class com.myapp.somesite.web.SomeSiteUserModel {
public static SomeSiteUserModel from(UserEntity userEntity) {
... initialize model ...
}
public UserEntity getModelObject() {
... get entity back ...
}
}
now all view based operations can hand off processing to the internal model object if that makes sense, otherwise it can customize them itself. Of course the problem with this is you have to re-write all the getters and setters you want for the entity (an issue that I've had to deal with, that is annoying) unfortunately that is a bit of a Java language issue
I just checked up with two of the last Spring projects I have worked on and in both places the following approach is taken:
In the JSP page for the form the change password field has a name that does not match the name of the password field in the User bean, so that it doesn't get mapped to the bean. Then in the onSubmit method there is a separate check whether a new password has been submitted, and if it has been, the change is reflected explicitly.
Поздрави,
Vassil
You can read the object from the database first and bind then the request. You can find an example at FuWeSta-Sample.
It uses a helper-bean which must be initialized by Spring.

Categories