Form binding using Map<String,String> doesn't work - java

http://www.playframework.com/documentation/2.1.x/JavaForms
The page states that, with the given example data model,
public class User {
public String email;
public String password;
}
you can bind a Map to the form, and populate the data model, like this:
#Test
public void bindTest() {
Form<User> form = Form.form(User.class);
Map<String,String> anyData = new HashMap<String,String>();
anyData.put("email","bob#gmail.com");
anyData.put("password", "password");
User user = form.bind(anyData).get();
assertEquals("bob#gmail.com", user.email);
assertEquals("password", user.password);
}
This doesn't work. It fails on assertEquals. However, when I add setters and getters to the Users's public fields, it works. Like this:
public class User {
public String email;
public String getEmail() { return email; }
public void setEmail(String value) { email = value; }
public String password;
public String getPassword() { return password; }
public void setPassword(String value) { password = value; }
}
I'd like to be able to do this without adding getters and setters.
After all, the page tells me that "Note: The underlying binding is done using Spring data binder." Okay, so it probably has to do with the way Spring data binding works, but I'm pretty sure the public fields would do the job, without getters and setters.
Any suggestions?

Related

How do you create Collections in Brightspot CMS using Java classes with the Dari framework?

import com.psddev.cms.db.Content;
import com.psddev.dari.db.Recordable;
public class MattContent extends Content {
private String tt;
private String uu;
public String getUu() {
return uu;
}
public MattContent setUu(String uu) {
this.uu = uu;
return this;
}
public String getTt() {
return tt;
}
public MattContent setTt(String tt) {
this.tt = tt;
return this;
}
#Recordable.DisplayName("Headline")
private String title;
#Recordable.DisplayName("Fields")
private String fields;
#Recordable.Regex(value=".+\\#.+\\..+", validationMessage="Use email format 'myemail#address.com'")
private String email;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
The code above renders individual fields in the UI from a Java class using the Dari framework in Brightspot CMS. I would like to do more than individual fields, but Collections as well.
I can see how to set up a Collection for users in the docs:
https://docs.brightspot.com/4.0/en/plugins-guide/collections/creating-collections.html
However, I cannot find the annotation in Dari to set this up for devs:
https://docs.brightspot.com/4.2/en/dari-guide/data-modeling/data-modeling-annotations.html
I'd really appreciate any help in pointing me to the right section of the documentation. This may be a vocabulary issue -- I may not be typing in the right words to get this information.
*"Cluster" isn't yielding the results I'm looking for either.
Thanks for your time and help.
Solution: There is no annotation needed for a collection. One can write a simple set or list:
private Set<Internal> internalSet;
private List<Internal> internalList;
The solution is so simple, I overlooked the obvious: annotations are extras in Dari, not essential for rendering content to Brightspot CMS' UI.

vavr add nested validations with validations combine

I have an input object as
class Person {
private String name;
private String email;
private String phone;
private Address address;
public static class Address {
private String city;
private String pincode;
private String street;
private AddrDetails details;
public static class AddrDetails {
private String state;
private String country;
}
}
}
I am using vavr Validations to validate the input
public static Validation<Seq<ConstraintViolation>, PersonDetailsModel> validatePerson(PersonDetailsRequest request) {
Validation
.combine(
validateName("name", request.getName()),
validateEmail("email", request.getEmail()),
validatePhone("phone", request.getPhone()),
validateAddress(request.getAddress())
).ap((name, email, phone, address) -> new PersonDetailsModel(name, email, phone, address);
}
public static Validation<Seq<ConstraintViolation>, Person.Address> validateAddress(
Person.Address request) {
return Validation
.combine(..
).ap((..) -> new Person.Address(..);
}
In the second function, it returns Seq of ConstraintViolation while validatePerson expects only ConstraintViolation which is why it is failing although I have to add one more level of nesting of validations for AddrDetails. How to handle nested objects validations with this approach.
I am not sure about how shall I go ahead?
In our project we call .mapError(Util::flattenErrors) after .ap. I have the feeling that there is a better way, but this at least solves the nesting.
The method in the Util class looks like this :
public static Seq<ConstraintViolation> flattenErrors(final Seq<Seq<ConstraintViolation>> nested) {
return nested
.flatMap(Function.identity())
.distinct(); // duplicate removal
}

Morphia - custom field with custom reader and writer

I want to add a custom type of field that will have a default behaviour.
my purpose is to handle all type of secret fields:
for example:
I have password field on user class, and I want password field to be encrypted on some way, so instead of:
#Entity
public static class User {
String name;
String pwd;
String pwdToken
public User() {
}
public User( string name, string password ) {
super();
this.pwd = password;
}
}
and then managing the decrypt and encrypt from outside - service or controller
I would have something like that:
#Entity
public static class User {
String name;
SecretField pwd;
public User() {
}
public User( string name, string password ) {
super();
this.name = name;
// this.pwd.set(password)
}
}
public final class SecretField implements Serializable {
private static final long serialVersionUID = 1L;
private String encryptedContent;
private String token;
public SecretField(String content) {
this.token = generateToken();
this.encryptedContent = decrypt(content, this.token);
}
// when especially called the decrypted pwd will be returned
public decrypt(){
decrypt(encryptedContent, token)
}
//here I should override the default output object - return this.encryptedContent instead of whole object
//???
}
This way, every time I have a secret field I can just use this class and the encrypting will be done automatically, And I won't need to manage the on each controller seperatly.
On update and insert, the password will be sent as decrypted string from client and on get the enrypted string will be returned.
Is it possible with morphia?
You can write a custom codec in 2.0 to do that for you. Prior to that you could write a life cycle event handler to do that. The docs for that can be found at https://morphia.dev

how spring-mvc finds the right class to instantiate and fill its data with POST-REQUEST fields

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.

How to represent java object as return type of service in .thrift file

I'm developing a service using apache thrift. I have a service named getUser which returns User object. I couldn't find any way to define user-defined data type as a return type for my service defined in .thrift file.
user.thrift file looks like:
service UserService
{
User getUser(1:i32 userId),
}
When I am compiling the user.thrift to generate java source code, I am getting "Type "User" has not been defined" error. Can anyone please help me, how to represent this user-defined java object as a data type in thrift.
The getUser method code in service implementation class:
#Override
public User getUser(int user id) throws TException {
// here is the code that fetch the user object from database
return user;
}
This is my User class, whose object is being returned by service getUser:
public class User {
private int userId;
private String name;
private String city;
private String country;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
}
The relevant IDL could look like this:
struct User {
1 : i32 userId
2 : string name
3 : string city
4 : string country
}
So that's pretty straightforward. With that, you have two options:
use the Thrift-generated class as the data object, replacing your existing class
write some code that converts the data back and forth.
Both options have their pros and cons. With the first approach, you will lose the getter-only for the Id, because the field must be read/writable. But you don't have to convert any data.
The second approach leaves you with the getter/setter structure you have right now, with some minor modifications (the factory pattern could be worth a look). You pay that with the burden of additional data conversion from Thrift into your class and back.
It depends on the exact requirements, which option is the better one for your case.

Categories