also I have a user dto class
class UserDto{
Long id;
String name;
String email;
String password
}
when user login is success, I wants to show response like this
{
"user":{
"id":"1",
"name":"imesh"
},
"token":{
"access_token":{
"token":"bhacvyusbi",
"expired_at":"20200210"
},
"refresh_token":{
"token":"bhacvyusbi",
"expired_at":"20200210"
}
}
}
so I have created a Response dto
class ResponseDto{
UserDto user;
AllTokenDto reponse;
}
class AllTokenDto{
TokenDto access_token;
TokenDto refresh_token;
}
class TokenDto{
String token;
Date expiredDate;
}
In here userData is which I am get the data from database
ResponseDto responseDto = new ResponseDto();
responseDto.setUser(modelMapper.map(**userData**, UserDto.class));
I have successfully added ResponseDto to UserDto data,
how to added tokens data to the ResponseDto.
Related
I have an existing system that uses string based unique IDs for users and I want to transfer that System into a Spring boot application. I want to creat a user so I send a POST request with the following content:
As you can see, the id gets ignored.
This is my Spring code for the user class:
#PostMapping("/user")
ResponseEntity addUser(User receivedUser) {
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
logger.info("Empfangener User: " + receivedUser.toString());
try {
User mailCheckUser = userService.getUserByMail(receivedUser.getEmail());
User nameCheckUser = userService.getUserByName(receivedUser.getUsername());
if (mailCheckUser != null){
return new ResponseEntity("Email already exists", HttpStatus.NOT_ACCEPTABLE);
}
if (nameCheckUser != null){
return new ResponseEntity("Username already exists", HttpStatus.NOT_ACCEPTABLE);
}
userService.addUser(receivedUser);
} catch (Exception userCreationError) {
return new ResponseEntity(receivedUser, HttpStatus.INTERNAL_SERVER_ERROR);
}
return new ResponseEntity(receivedUser, HttpStatus.OK);
}
public void addUser(User user) {
userRepository.save(user);
}
And this is my user class:
#Entity
#Table
public class User {
#Id
#Column(unique =true)
private String id;
private #Column(unique =true)
String username;
private #Column(unique =true)
String email;
private #Column(unique =true)
String simpleAuthToken;
private
String password;
/*REDACTED*/
private
boolean isBlocked;
public User(String id, String name, String email, boolean isBlocked) {
this.id = id;
this.username = name;
this.email = email;
this.simpleAuthToken = simpleAuthToken;
this.isBlocked = false;
}
public User() {
}
/*GETTERS AND SETTERS ARE HERE, BUT I CUT THEM FOR SPACING REASONS*/
}
And this is the Spring Output:
My expected outcome would be that Spring would recognize the id and then create a user with the id I provided. Why is the id always null?
EDIT: If I put the ID in a Put or Get Mapping as Path variable, like so:
#PutMapping("/user/{id}")
ResponseEntity updateUser(#PathVariable String id, User receivedUser) {}
then it gets read and recognized, but it will still be null in the receivedUser
First add #RequestBody in the post request body. In the Post request (/test/user) your passing some params but in the method level not received.
If you want receive id from postman then add #RequestParam("id")String id in the method level.
How you generating unique Id by manually or some generators?
And double check user id at the database console level.
I user a CRUDRepository in my spring data redis project to persist a redis hash in my redis cluster. i have rest api written to persist and get thte values of the data. this works fine.
however my entity annotated with RedisHash is being saved as a set / and i am not able to look inside the value using redis cli.
how do i look inside a set data type(without popping) in redis cli
i looked at redis commands page https://redis.io/commands#set
i only get operations which can pop value . i neeed to simply peek
EDIT:
to make things clearer, i am using spring crudrepo to save the user entity into redis data store. the user entity gets saved as a set data type.
when i query back the user details, i can see entire details of the user
{
userName: "somak",
userSurName: "dattta",
age: 23,
zipCode: "ah56h"
}
i essentially want to do the same using redis cli... but all i get is
127.0.0.1:6379> smembers user
1) "somak"
how do i look inside the somak object.
#RestController
#RequestMapping("/immem/core/user")
public class UserController {
#Autowired
private UserRepository userRepository;
#RequestMapping(path = "/save", method = RequestMethod.GET, produces = "application/json")
#ResponseStatus(HttpStatus.OK)
public void saveUserDetails() {
User user = new User();
user.setAge(23);
user.setUserName("somak");
user.setUserSurName("dattta");
user.setZipCode("ah56h");
userRepository.save(user);
}
#RequestMapping(path="/get/{username}", method = RequestMethod.GET, produces = "application/json")
public User getUserDetails(#PathVariable("username") String userName) {
return userRepository.findById(userName).get();
}
}
#Repository
public interface UserRepository extends CrudRepository<User, String>{
}
#RedisHash("user")
public class User {
private #Id String userName;
private #Indexed String userSurName;
private #Indexed int age;
private String zipCode;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserSurName() {
return userSurName;
}
public void setUserSurName(String userSurName) {
this.userSurName = userSurName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getZipCode() {
return zipCode;
}
public void setZipCode(String zipCode) {
this.zipCode = zipCode;
}
}
I don't understant your descr with your problem, but I understand your title.
In redis set, the member is always string type.
I hope you can offer more info about UserRepository.save:
User user = new User();
user.setAge(23);
user.setUserName("somak");
user.setUserSurName("dattta");
user.setZipCode("ah56h");
userRepository.save(user);
And you can check your redis data and check data type when rest api invoked.
I have my domain class as follows
#Getter
#Setter
public class Student {
private Long id;
private String firstName;
private String lastName;
}
And I have this controller
#RestController
#RequestMapping("/student")
public class StudentController {
#PostMapping(consumes = "application/json", produces = "application/json")
public ResponseEntity<Student> post(#RequestBody Student student) {
//todo save student info in db, it get's an auto-generated id
return new ResponseEntity<>(student, HttpStatus.CREATED);
}
}
Now what I want is to configure serializer in a way that it ignores the id field on income, so I get only firstName and lastName, but serialize it when I'm returning the object to the caller.
Its easy to use it with jackson. There is an annotation named #JsonProperty(access = Access.READ_ONLY) where you can define if the property should be de- or serialized. Just put that annotation on your id field.
#JsonProperty(access = Access.READ_ONLY)
private Long id;
The Controller:
#PostMapping(consumes = "application/json", produces = "application/json")
public ResponseEntity<Student> post(#RequestBody Student student) {
//here we will see the that id is not deserialized
System.out.println(student.toString());
//here we set a new Id to the student.
student.setId(123L);
//in the response we will see that student will serialized with an id.
return new ResponseEntity<>(student, HttpStatus.CREATED);
}
Requestbody:
{
"id":1,
"firstName": "Patrick",
"lastName" : "secret"
}
Output of toString():
Student [id=null, firstName=Patrick, lastName=secret]
Response:
{
"id": 123,
"firstName": "Patrick",
"lastName": "secret"
}
P.S. It will also work if you dont send an id property:
{
"firstName": "Patrick",
"lastName" : "secret"
}
I'm trying to send collections to my spring MVC controller:
#RequestMapping("/postUsers.do")
public #ResponseBody ResponseDTO postUsers(#ModelAttribute("mapperList") MapperList mapperList) {
//prints {"users":null}
System.out.println(new ObjectMapper().writeValueAsString(mapperList));
return new ResponseDTO();
}
this is the code posting my users :
public ResponseDTO postUsers(ArrayList<User> users) {
ResponseDTO serverResponse = null;
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestMethod("POST");
// prints {"users":[{"property1":"x","property1":y}]}
System.out.println(objectMapper.writeValueAsString(new MapperList(users)));
objectMapper.writeValue(connection.getOutputStream(), objectMapper.writeValueAsString(new MapperList(users)));
//blabla ...
}
and this is the object containing my list :
public class MapperList implements Serializable {
private static final long serialVersionUID = 8561295813487706798L;
private ArrayList<User> users;
public MapperList() {}
public MapperList(ArrayList<User> users) {
this.setUsers(users);
}
public ArrayList<User> getUsers() {
return users;
}
public void setUsers(ArrayList<User> users) {
this.users = users;
}
}
and this is the users type to post:
public abstract class User implements Serializable {
private static final long serialVersionUID = -1811485256250922102L;
private String property1;
private String property2;
public User() {}
public User(String prop1, String prop2) {
// set properties
}
// getters and setters
}
the problem is, when I output the value of the users's array before to post it to the controller, I got the following json value :
{"users":[{"property1":"x","property1":y}]}
but in the controller, when I print what I get from the request body, I only get :
{"users":null}
I also tryed with the annotation #RequestBody instead of #ModelAttribute("mapperList") and a JSONException is displayed :
*A JSONObject text must begin with '{' at 1 [character 2 line 1]\r\n*
My array list of users contains only one user that should be displayed. I don't understand why this doesn't work...
Thanks for any help !
You can chnage your MapperList class definition as public class MapperList extends ArrayList<User>{ ..} you dont need to define any instance variable like private ArrayList users inside MapperList class. Use #Requestbody annotation. You will be able to use MapperList as a ArrayList
Try to use:
public class MapperList{
private List<User> users;
//setter and getter
//toString
}
public class User{
private String property1;
private String property2;
//getter + setter
}
json:
{"users":[{"property1":"x", "property2":"y"}]}
in controller use #RequestBody. In that case Jackson will map your json to ArrayList of users.
#ResponseStatus(HttpStatus.OK)
#RequestMapping("/postUsers.do")
public #ResponseBody ResponseDTO postUsers(#RequestBody MapperList users) {
System.out.println(users);
return null;
}
no need to get objectMapper in that case. Don't forget to set content-type in request header to application/json. It required by Spring to handle #RequestBody processing.
If not working try to change MapperList:
List<User> users = new ArrayList<User>();
On the server side keep the #RequestBody annotation:
public #ResponseBody ResponseDTO postUsers(#RequestBody MapperList mapperList)
...
But this line causes problems:
objectMapper.writeValue(
connection.getOutputStream(),
objectMapper.writeValueAsString(new MapperList(users))
);
First it converts the object to JSON and then again uses objectMapper to JSON-encode the string into output stream. Try the following instead:
connection.getOutputStream().write(
objectMapper.writeValueAsString(new MapperList(users))
.getBytes("UTF-8")
);
or directly output to stream:
objectMapper.writeValue(
connection.getOutputStream(),
new MapperList(users))
);
Zbynek gave me part of the answer. Indeed
objectMapper.writeValue(
connection.getOutputStream(),
objectMapper.writeValueAsString(new MapperList(users))
);
doesn't work properly in my case
But moreover, my User class was an abstract class, with many type of User as subclasses. so the #RequestBody annotation couldn't work without specified the object type in the Json.
I used the following annotations on User class to make it working :
#JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, property = "type")
#JsonSubTypes({
#JsonSubTypes.Type(value = SubClassA.class, name = "a"),
#JsonSubTypes.Type(value = SubClassB.class, name = "b")
})
Thanks a lot for all your answers.
My model is
#Entity
#Table(name = "user")
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name="name")
private String name;
#Column(name="email")
private String email;
//getter & setter
}
My controller is
#RequestMapping(value = "user/userProfile", method = RequestMethod.POST)
public String saveUserProfile(#Valid UserProfile userProfile, #RequestParam("file") MultipartFile file,
BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("userProfile", userProfile);
return "userprofileform";
}
userProfileService.saveUserProfile(userProfile);
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/user/home";
}
#RequestMapping("/user/userProfile/new")
public String newUserProfile(Model model) {
UserProfile profile = userProfileService.getUserProfileByUserId(userService.getLoggedInUser().getId());
model.addAttribute("userProfile", profile);
return "userprofile";
}
Repository is
#Transactional
public interface UserProfileRepository extends CrudRepository<UserProfile, Long>{
}
When I am creating first time userProfile it creates successfully but when I tried to update same it create new entry.
But in this controller when I use findone() and copy all information it works fine.
Same save method replaced below like :
public String saveUserProfile(#Valid UserProfile userProfile, #RequestParam("file") MultipartFile file,
BindingResult bindingResult, Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("userProfile", userProfile);
return "userprofileform";
}
UserProfile tempProfile = userProfileService.getUserProfileByUserId(userService.getLoggedInUser().getId());
try {
if (tempProfile != null) {
tempProfile.setName(userProfile.getName());
tempProfile.setEmail(userProfile.getEmail()); userProfileService.saveUserProfile(tempProfile);
} else {
userProfile.setUserId(userService.getLoggedInUser().getId());
userProfileService.saveUserProfile(userProfile);
}
} catch (IOException e) {
e.printStackTrace();
}
return "redirect:/user/home";
}
Is this write way or how can we update record?.
Or saving in session attribute (#SessionAttributes("yourAttributeName")) is only the write way?
Make sure the userProfile object has an id assigned. If your object doesn't have an id, hibernate assumes it's a new entity and therefore it creates a new record in the database.
You need to confirm that when you want to do an update the UserProfile has an id. Put a debug point at: profileRepo.save(userProfile) to confirm this, as a new Entity will be created if no id exists, and should be updated if the id already exists.