Springboot oauth2 authorization server json mapping - spring-boot

serialization add the class path on the objet and transforme the object on array.
recently I changed versions of pringboot from 2.5 to 2.7 usually I didn't need to configure Jackson json to return the object
so when I had an object of a class such as this, ResponseEntity on controller returns me as described in bast
Class model
#Data
public class User implements Serializable {
private String firstName;
private String lastName;
private Date createAt;
private Role role;
}
JSON Response
{
'firstName': "string",
'lsatName':'string',
'createAt': 'string'
'role': {
id: 'string',
name: 'string'
}
}
but now for the same class i got back something like:
{
'#class': 'class_path,
'firstName': "string",
'lsatName':'string',
'createAt': [java.sql.timestamp: "string"]
'role': {
#class: 'class_path',
id: 'string',
name: 'string'
}
}
how can I go back to the first result model
I want to get just and object whitout class path

Related

added data to the custom Dto class

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.

Unable to convert pathvariable to object

I want to have an object as a path variable but I get the below exception when testing. How can I fix this
#Validated
#RestController
#RequestMapping("/test/api")
public class MyRestController {
#GetMapping("/data/{id}")
public Data getData(#PathVariable #Valid IdData id) {
return new Data();
}
}
#Data
public class IdData {
private Integer id;
public IdData(Integer id) {
this.id = id;
}
}
Exception:
org.springframework.web.method.annotation.MethodArgumentConversionNotSupportedException:
Failed to convert value of type 'java.lang.String' to required type
'com.test.IdData'; nested exception is
java.lang.IllegalStateException: Cannot convert value of type
'java.lang.String' to required type 'com.test.IdData': no matching
editors or conversion strategy found
From "/data/{id}" you will get an id which is an integer but the method parameter is trying to get IdData value which is incompatible.
#Validated
#RestController
#RequestMapping("/test/api")
public class MyRestController {
#GetMapping("/data/{id}")
public Data getData(#Valid #PathVariable int id) {
return new Data();
}
}
Output:-
{
"repository": {
"metricName": "spring.data.repository.invocations",
"autotime": {
"enabled": true,
"percentilesHistogram": false,
"percentiles": null
}
}
}
you could change your #PathVariable Data Type from IdData to an Integer. Just add some logic to get the IdData by the id in path, which can be done by using JPA's findById() method. It might also be easier to pass in an integer in the path rather than an entire object.

How to query nested objects from MongoDB using Spring Boot (REST) and TextQuery?

I am writing RESTful API to search MongoDB collection named 'global' by criteria using TextQuery. My problem is that I cannot access nested object fields when doing query.
For example this works:
GET localhost:8080/search?criteria=name:'name'
And this does not:
GET localhost:8080/search?criteria=other.othername:'Other Name'
I have MongoDB json structure (imported from JSON into 'global' collection as whole nested objects)
[{
"name": "Name",
"desc": "Desc",
"other" {
"othername": "Other Name",
}
},
{
"name": "Name",
"desc": "Desc",
"other" {
"othername": "Other Name",
}
}
]
And classes (with getters & setters & etc):
#Document(collection="global")
public class Global{
#TextIndexed
String name;
#TextIndexed
String desc;
Other other;
...
}
public class Other{
String othername;
...
}
My controller has method
#GetMapping("/search")
public Iterable<Global> getByCriteria(#RequestParam("criteria") String criteria) {
...
}
And I am trying to write text search with
public Iterable<Global> findByCriteria(String criteria) {
TextCriteria criteria = TextCriteria.forDefaultLanguage().matching(criteria);
TextQuery query = TextQuery.queryText(criteria);
return mongoTemplate.find(query, Global.class);
}
You need to add #TextIndexed to your other field.
public class Global{
#TextIndexed
String name;
#TextIndexed
String desc;
#TextIndexed
Other other;
...
}
Note: All nested object fields are searchable
or you may add #TextIndexed for each nested object field:
public class Other {
#TextIndexed
String othername;
...
}

Spring rest controller giving unsupported content type

Hello all here is what i have:
StockController.java
#RestController
public class StockController {
#Autowired
private StockRepository repository;
#RequestMapping(value = "stockmanagement/stock")
public ResponseEntity<?> addStock(#RequestBody String stock
) {
System.out.println(stock);
return new ResponseEntity<>(HttpStatus.OK);
}
when I make a request like so using chrome advanced rest extension :
Raw Headers
Content-Type: application/json
Raw Payload
{"stock": {"productId": 2, "expiryAndQuantity" : {}, "id": 0}}
It works fine in that out comes a string of json
However when i try to replace String stock with Stock stock where stock looks like this:
public class Stock {
#Id
private String id;
private String productId;
private Map<LocalDateTime, Integer> expiryAndQuantity;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public Map<LocalDateTime, Integer> getExpiryAndQuantity() {
return expiryAndQuantity;
}
public void setExpiryAndQuantity(Map<LocalDateTime, Integer> expiryAndQuantity) {
this.expiryAndQuantity = expiryAndQuantity;
}
#Override
public String toString() {
return String.format(
""
);
}
}
I get an error where by the following is fed back to me:
"status": 415
"error": "Unsupported Media Type"
"exception": "org.springframework.web.HttpMediaTypeNotSupportedException"
"message": "Content type 'application/json;charset=UTF-8' not supported"
"path": "/stockmanagement/stock"
My question is; how do i create a request which maps to my Stock object.
You can try with #JsonRootName annotation, by default Spring serialize using no root name value. like this:
{"productId": 2, "expiryAndQuantity" : {}, "id": 0}
But if you want that your serialization has a rootname you need to use #JsonRootName annotation.
#JsonRootName(value = "Stock")
And it'll produce something like this
{"Stock": {"productId": 2, "expiryAndQuantity" : {}, "id": 0}}
You can see more here
http://www.baeldung.com/jackson-annotations
instead of accepting a String Accept a Stock object.and accept it from a post request than having a get request
#RequestMapping(value = "stockmanagement/stock",method=RequestMethod.POST)
public ResponseEntity<?> addStock(#RequestBody Stock stock){
}
and your request should be sent like this
{
"productId": 2
,"expiryAndQuantity" : null
,"id": 0
}
all parameter names should be equal to the objects filed names,since spring has jackson binders on class path and object will be created inside the controller method. if you are planning on passing different parameters from the post request you can use
#JsonProperty("pid")
private String productId;
on the field name.

how to serialize multi-level json using jackson in spring?

This is the response body that is expected out the endpoint /foo/bar.
As you can see, this is nested json and hence for each level do I require a Java object. what is the efficient way to construct this?. I am using Spring 4.1 which in turn uses Jackson to serialize POJOs.
{
"user": {
"status": {
"state": "active",
"message": [
"registered on 01.10.2015"
]
}
},
"features": {
"xbox": {
"state": "enabled",
"message": [
"foo",
"bar"
]
},
"playstation": {
"state": "disabled",
"message": [
"hello ",
"world"
]
}
}
}
Here is something I have thought
#RequestMapping("foo/bar")
#ResponseBody
public Result getData(long id){
Result result = getUserData(id);
return result;
}
public class Result {
private User user;
private List<Feature> features;
//getters and setters
}
public class Status {
private State state;
private Message messages;
//getters and setteers
}
public class State {
private String state;
//getters and setters
}
public class Message {
private List<String> messages;
//getters and setters
}
Similarly for "features" node, I will construct Java POJO for each level of Json object. I am aware of using objectMapper and JsonNode but wondering if it is possible to effectively construct nested json using java objects.
Classes like State could be an enum, if you know for sure there will only be a limited domain of values. And Message shouldn't be a separate class- just embed List<String> message directly in Status.
If you want a more compact representation, you can always provide your own serializer/deserializer classes to customise the translation.

Resources