Passing data from a form to a REST endpoint - java

I'm kinda new to writing REST endpoints thus this question.
I'm writing a REST endpoint that should support a form submission in iOS that registers an User.
This is my User class.
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long Id;
private String username;
private String email;
private String password;
}
This is the controller user signup signature that I've been asked to work with,
#RestController
public class RegistrationController {
#RequestMapping(value = "/user/signup",
method = RequestMethod.POST,
consumes = {"application/json"})
public ResponseEntity<?> showRegistrationForm(#RequestBody User user) {
try{
//persist the User
return new ResponseEntity(HttpStatus.OK);
}catch(Exception e){
}
return new ResponseEntity(HttpStatus.BAD_REQUEST);
}
}
The user object is provided to me using the following JSON payload,
{
"username": "Something",
"email": "Something",
"password": "password"
}
What I don't understand is how do I grab the fields posted from the form and convert them to the user in a POST request. Wouldn't I need to change the parameters to string, validate them and then compose the User object. Or just what is the right way of doing this.
Any help appreciated.

Related

#JsonIgnore field is not consuming data from Postman

I have used the #JsonIgnore annotation to prevent exposing the password to the user while sending user details to the user:
public class UserDto {
private String username;
#JsonIgnore
private String password;
}
Below is the response of user API:
{
"username": "test12"
}
But while saving the new user when I am hitting the save API and send
below data, my controller method is consuming null password because of
#JsonIgnore and getting null pointer exception;
{
"username": "test1225",
"password": "admin"
}
Controller method:
#RequestMapping(value = "/addAccount", method = RequestMethod.POST)
public ResponseEntity<Void> addAccount(#RequestBody UserDto userDto) {
User user = new User();
user.setUsername(userDto.getUsername());
user.setPassword(userDto.getPassword());
userService.saveUser(user);
return new ResponseEntity<Void>(HttpStatus.CREATED);
}
Is there any way to ignore the Password parameter when returning
response to the user and not to ignore the password field value when
getting password parameter in request body in controller method?
You can use JsonViews to specify which fields should be included during serialization/deserialization. Take a look at this blog post to learn about JsonViews - http://www.baeldung.com/jackson-json-view-annotation.
For your issue, you can create a view called UserResponse.
public class UserResponse {
}
And annotate the fields of UserDto which you want to return with #JsonView(UserResponse.class)
public class UserDto {
#JsonView(UserResponse.class)
private String username;
private String password;
}
And in your controller, add JsonView annotation on the return type.
public #JsonView(UserResponse.class) ResponseEntity<Void> addAccount(#RequestBody UserDto userDto) {

How to indicate required properties for an object for swagger-ui

I have simple CXF-REST application for which for one of the services', I have an object as input. One of the parameters are mandatory for successful validation, however, swagger-ui shows optional or empty.
How to update it to show 'required' or a star mark ?
I tried using #ApiModelProperty(required=true), however no luck.
#Path("/user")
#Api(value = "/user", description = "User Service")
public interface UserService {
#POST
#Path("/saveUser")
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
#ApiOperation(value = "Save User details to backend", response = User.class)
public User saveUser(User user);
}
#ApiModel(description = "User")
#XmlRootElement
public class User {
#ApiModelProperty(value = "", required = true)
private String name;
private Integer age;
//getters and setters
}
We use swagger-annotations_2.10-1.3.0.jar,
swagger-core_2.10-1.3.0.jar,
swagger-jaxrs_2.10-1.3.0.jar in our application.
ScreenShot is in the link below
Swagger-required-properties
The swagger-ui.js javascript file can be updated as below, so that the 'required' string can appear in the model section for the specified attribute.
if(!propertyIsRequired) {
html += ', <span class="propOptKey">optional</span>';
} else {
html += ', <span class="propOptKey">required</span>';
}

#valid annotation sends exception in response to rest service

I am using custom validation in my rest web services.
#PUT
#Path("/{accountId}")
#Consumes({MediaType.APPLICATION_JSON})
public Response update(
#NotNull #ValidUUID #PathParam("accountId") UUID accUUID,
#NotNull #Valid Account changedAcc) {
synchronized (LOCK_MANAGER.getLock(accUUID)) {
return accHelper.update(this.getCurrentUser(), accUUID, changedAcc);
}
}
here is a glimpse at my Account class
#Table(keyspace = "Randomss", name = "accounts")
public class Account {
#PartitionKey
#Column(name = "id")
#JsonIgnore
private UUID id;
#Column(name = "acc_type")
#NotNull
#ValidString
#JsonIgnore
private String accType;
Now I send JSON data to this web service to update account,
but if I send some wrong json data
(e.g acc_type is expected as string and I send numeric data)
then it throws an exception.
How do I get it to send an error message instead of throwing an exception
(specifically, I want to send the error message)?
You need to write a javax.ws.rs.ext.Provider that implements an javax.ws.rs.ext.ExceptionMapper.
For example a generic ValidationExceptionMapper might look like:
#Provider
public class ValidationExceptionMapper
implements ExceptionMapper<ValidationException> {
public Response toResponse(ValidationException e) {
return Response.status(BAD_REQUEST).build();
}
}
You can choose a more appropriate response to return.

Error org.springframework.web.HttpMediaTypeNotSupportedException

i have a problem with rest and method post on my controler i have this 2 class the first is user in my class user i have my class with the getters and setter and a default contructor because for the finally I would like use Hibernate .:
#Entity
#Table(name="Utilisateur") // mapping with hibernate (but not using in this situation)
public class User {
#Id
private long id;
#Column(name="nom")
private String nom;
#Column(name="prenom")
private String prenom;
#Column(name="admin")
private boolean admin;
#Column(name="actif")
private boolean actif;
#Column(name="logins")
private String logins;
#Column(name="email")
private String email;
#Column(name="naissance")
private String naissance;
#Column(name="pwd")
private String pwd;
#Column(name="compte")
private String compte;
public User(){
}
/*
with getter and setter.
*/
}
and my class controler (User controller) : is using for make the api principally post api .
#RestController
public class UserController {
#RequestMapping(
value="/api/greetings/post",
method = RequestMethod.POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces=MediaType.APPLICATION_JSON_VALUE
)
#ResponseBody
public ResponseEntity<User> getByEmail(#RequestBody User user){
if(user==null){
return new ResponseEntity<User>(HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity<User>(user, HttpStatus.OK);
}
and i get this erreur I am using postman for make the query and in parameter of my query I send this Json query :
{"id":"3","nom":"Gille","prenom":"Laurent","admin":"1","actif":"0","logins":"gilaur","email":""toto#hotmail.com,"naissance":"1990/09/09","pwd":"gal","compte":"autre"}
And i get this error :
{"timestamp":1457906727481,"status":415,"error":"Unsupported Media Type","exception":"org.springframework.web.HttpMediaTypeNotSupportedException","message":"Content type 'text/plain;charset=UTF-8' not supported","path":"/api/greetings/post/"}
Thank you
you are change headers content-type application/json in Postman because you try set text/plain

Spring REST Controller Saving JSON Post

I am stuck on something and after a day of searching and trying different things I am throwing in the towel. I have 2 basic domains, a blog post and an author. I have left a little code out to keep this post short.
#Entity
public class Post {
#Id #GeneratedValue
private Long id;
private String title;
#Column(columnDefinition = "TEXT")
private String body;
#Column(columnDefinition = "TEXT")
private String teaser;
private String slug;
#CreatedDate
#Temporal(TemporalType.TIMESTAMP)
private Date postedOn;
#ManyToOne
private Author author;
// getters & setters
}
#Entity
public class Author {
#Id
#GeneratedValue
private Long id;
private String firstName;
private String lastName;
private String email;
// getters & setters
}
The controller looks like this
#RestController
#RequestMapping("/posts")
public class PostController {
private PostService postService;
#Autowired
public PostController(PostServiceImpl postService){
this.postService = postService;
}
#RequestMapping( value = "/", method = RequestMethod.GET )
public Iterable<Post> list(){
return postService.list();
}
#RequestMapping( value = "/", method = RequestMethod.POST )
public Post create(#RequestBody Post post){
return postService.save(post);
}
#RequestMapping( value = "/{id}", method = RequestMethod.GET )
public Post read(#PathVariable(value="id") long id){
return postService.getPost(id);
}
#RequestMapping( value = "/{id}", method = RequestMethod.PUT )
public String update(#PathVariable(value="id") int id){
return "post.update()";
}
#RequestMapping( value = "/{id}", method = RequestMethod.DELETE )
public String delete(#PathVariable(value="id") int id){
return "post.delete()";
}
}
And all the service method does is take the Post POJO and call the save method on the repository. This is my question and I feel dumb for even asking it. When I post JSON from Postman with no author (null) everything works fine. I am just not sure how the heck to post a json object with a new author or an existing one.
This works
{
"title" : "A new post created from JSON",
"slug" : "a-new-post",
"teaser" : "post teaser",
"body" : "post body",
"postedOn" : "2015-11-07"
}
When I try and post this JSON
{
"title" : "A new post created from JSON",
"slug" : "a-new-post",
"teaser" : "post teaser",
"body" : "post body",
"postedOn" : "2015-11-07",
"author" : {
"firstName": "Joe",
"lastName": "Smith",
"email": "jsmith#gmail.com"
}
}
I get the following error
{
"timestamp": 1447018768572,
"status": 500,
"error": "Internal Server Error",
"exception": "org.springframework.dao.InvalidDataAccessApiUsageException",
"message": "org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.therealdanvega.domain.Post.author -> com.therealdanvega.domain.Author; nested exception is java.lang.IllegalStateException: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : com.therealdanvega.domain.Post.author -> com.therealdanvega.domain.Author",
"path": "/posts/"
}
You first need to persist the Author. From the Post point of view, the Author you are presenting to it is Transient as it has no id, thus mapping cannot be done between Post and Author.
So create a persistent object of the Author and then insert it into the Post entity.

Categories