I was wondering if there was a way in Spring Boot to pass the IDs of an object in an Array which Spring Boot will then get the object details for rather than the full object
This is an issue for me as to find the object, it appears Spring Boot wants the full object which will not work in my case
For example
{
"request": [
"e77d8168-4217-43c9-a6dd-fb54957d1302"
]
}
Rather than having to pass
{
"request": [
{
"uuid": "e77d8168-4217-43c9-a6dd-fb54957d1302",
"name": "Object 1"
}
]
}
Yes. The problem is probably with the class you are using to map your List<String>. It must match your json. Your controller should be like:
#RestController
public class IdsController {
#PostMapping("endpoint")
public void postIds(#RequestBody IdRequest idRequest){
idRequest.getRequest().forEach(System.out::println);
}
}
And the request object:
public class IdRequest {
private List<String> request;
public List<String> getRequest() {
return request;
}
}
Related
i'm trying to consume a Json response using RestTemplate in java with Jackson annotations, and i have a resource that have many name properties like so:
{
-name1:{
id:2,
price:12,
name:"Bob:
},
-name2:{
id:111,
price:1.1,
name:"Ron:
},
-name3:{
id:10,
price:33,
name:"jhon:
},
}
and the list go on like this.
this is my code of how to get one of the entities, like name1 object:
public class Class1 {
private RestTemplate restTemplate;
private String url = "https://url.com/api";
private Response response;
private Market market ;
public class1(){
restTemplate = new RestTemplate();
response = restTemplate.getForObject(url,Response.class);
}
#Override
public Market getResults() {
market = response.getResult();
System.out.println(Market);
return null;
}
}
and the response class is like so :
#JsonIgnoreProperties(ignoreUnknown = true)
#Getter
#Setter
#NoArgsConstructor
public class Response {
#JsonProperty("name1")
private Market result;
}
how can i get all those elements as an array or ArrayList?
this API is from 3rd party website and there's many entities liek that in the Json response.
thanks in advance.
So in the Json above, it is not an array but a list of key value pair.
This is what an array looks like in Json:
{
marketResults: [
{
id:2,
price:12,
name:"Bob:
},
{
id:111,
price:1.1,
name:"Ron:
},
{
id:10,
price:33,
name:"jhon:
}
]
}
Then what you could have done is:
public class Response {
private List<Market> marketResults;
}
But since your example is a map, you need to to use a MAP
public class Response {
private Map<String, Object > marketResults;
}
That post actually similar to yours: Reading JSON map structure via spring boot
If you can use Gson library that has native support for this use-case.
Keeps your code clean and typed.
#Getter
#Setter
public class Response {
#SerializedName(value = "name1", alternate={"name2","name3"})
private Market result;
}
#SerializedName is the #JsonProperty equivalent in Gson.
With the below GET request:
ResponseEntity<String> entity = restTemplate.exchange(uri, HttpMethod.GET, requestEntity, String.class );
entity.getBody();
returns a JSON String like this:
{"userRegistrations":[{"userRegistrationToken":"fb398972","userRegistrationTokenAlias":"87f15f8"}]}
But I want to make this work with an object not with a string. So with the code below I receive a UserRegistrations object with a null UserTokenResponse List
ResponseEntity<UserRegistrations> entity = restTemplate.exchange(uri, HttpMethod.GET, requestEntity, UserRegistrations.class );
entity.getBody();
And my domain class looks like this:
public class UserRegistrations {
List<UserTokenResponse> userRegistrationList;
//..getters and setters
}
public class UserTokenResponse {
private String userRegistrationToken;
private String userRegistrationTokenAlias;
//getters and setters
}
What am I missing?
Assuming you're using Jackson, RestTemplate automatically registers a MappingJackson2HttpMessageConverter which configures the underlying ObjectMapper to ignore unknown properties.
The JSON object has a single attribute named userRegistrations, whereas your Java class has a single attribute named userRegistrationList. They don't match.
They need to match, or you need to add a #JsonProperty annotation of the attribute to make Jackson serialize/parse it as userRegistrations.
This happens when your class property names doesn't match with the JSON property names coming in the response. For instance take the below example
public class ScheduledCallbacks {
private List<Callback> callbacks;
public List<Callback> getCallbacks() {
return callbacks;
}
public void setCallbacks(List<Callback> callbacks) {
this.callbacks = callbacks;
}
#Override
public String toString() {
return "ScheduledCallbacks [callbacks=" + callbacks + "]";
}
}
and if the response is the following way
{
"scheduledCallbacks": [
{
"sessionId": "string",
"customerNbr": "string",
"topicName": "string",
"desiredTime": "string",
"callbackState": "string",
"serviceName": "string",
"expirationTime": "string",
"programCode": "string"
}
]
}
Then you get null response because the name scheduledCallbacks in the JSON response doesn't match with the name callbacks in class.
But if your class is as following
public class ScheduledCallbacks {
private List<Callback> scheduledCallbacks;
public List<Callback> getScheduledCallbacks() {
return scheduledCallbacks;
}
public void setScheduledCallbacks(List<Callback> scheduledCallbacks) {
this.scheduledCallbacks = scheduledCallbacks;
}
#Override
public String toString() {
return "ScheduledCallbacks [scheduledCallbacks=" + scheduledCallbacks + "]";
}
}
Then you get the expected response in response entity
I encountered a similar error and it was returning null too. The problem is over when Object.class is replaced with the name of the class we want to convert on the client side.
Like that:
Token = restTemplate.exchange(uri, HttpMethod.POST, request, Object.class);
the problem was probably due to the fact that it is not directly compatible with the class we want to convert.
Let's say i have posted JSON to server as following:
{
warFile: {name: "test1", dependencies: [test0, test2]},
param: {build: true, test: true}
}
And i have 3 classes as following:
public class WarFile{
private String name:
private String[] dependencies;
public void setName(){...};
public String getName(){...};
public void setDependencies(){...};
public String[] getDependencies(){...};
}
public class Param{
private boolean build;
private boolean test;
public void setBuild(){...};
public boolean isBuild(){...};
public void setTest(){...};
public boolean isTest(){...};
}
public class Command{
private WarFile warFile;
private Param param;
private void setWarFile(){...};
private WarFile getWarFile(){...};
private void setParam(){...};
private Param getParam(){...};
}
Controller as below:
#RequestMapping(value = "/test.ajax", method = RequestMethod.POST)
public #ResponseBody
BuildResult buildWar(#RequestBody Command cmd) {
return logic.build(cmd.getWarFile(), cmd.getParam());
}
And since warFile and param in Command are not a primitive type, I always get the following error:
The request sent by the client was syntactically incorrect.
I'm sure that there is not any problem if all the properties in Command are primitive type. But how comes this error happened? I mean, the objects are simple, no need to write a custom deserializer for them.
"The request sent to the client was syntactically incorrect" means there is something wrong with the content of the request you sent, not necessarily your controller or Spring configuration. First off, your JSON is not valid. Jackson can't properly map the JSON to the objects it should represent. It should be:
{
"warFile": {
"name": "test1",
"dependencies": ["test0", "test2"]
},
"param": {
"build": true,
"test": true
}
}
Second, make sure the content type is application/json. Lastly, why does your Command object have private getters/setters, and your setters don't have field parameters?
Is your request mapping is /test.ajax or /test in your html <form>?
Have you added jackson mapper jar dependency ? if yes next solution would be escape your quotes i guess. this might help
Spring MVC : The request sent by the client was syntactically incorrect
Getting HTTP status 400 - The request sent by the client was syntactically incorrect: using curl to post/put json request
In my ajax response, I want to return a JSON result.
I'm using spring mvc, and I have jackson in my pom.xml already.
Now in my controller's action I have:
#ResponseBody
#RequestMapping(value = "/someAjaxResponse", method = RequestMethod.POST)
public String someAjaxResponse(HttpServletRequest request, HttpServletResponse response) {
}
What built in java datastructure/type do you suggest I use so I can then convert it to json using jackson?
I don't want to create a new class for each response type, so I'm looking for a good general purpose java type for this purpose.
Suggestions?
For converting to json, which method would be best as I know jackson has multiple ways converting objects, like ObjectMapper which I believe you create a single instance of and re-use throughout the entire application? So does that mean I mark it as final?
The answer depends on your use case. My suggestion is that you create a custom value object that exactly fit your needs, return it and then let Jackson handle the serializaion for you:
#ResponseBody
#RequestMapping(value = "/someAjaxResponse", method = RequestMethod.POST)
public CustomValueObject someAjaxResponse(HttpServletRequest request, HttpServletResponse response) {
}
All that you have to do is to add the <mvc:annotation-driven /> or #EnableWebMvc to your application context, add the Jackson dependencies to your classpath and then the object will be serialized to JSON automatically because you use the #ResponseBody annotation.
Read more about the MappingJacksonHttpMessageConverterin the Spring reference manual:
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/mvc.html#mvc-config-enable
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/remoting.html#rest-mapping-json-converter
Note, the returned object can have complex structure. Imagine that you would like to provide person data to the client, then you can return a Person object from your controller method:
public class Person {
public String getFirstName() {...}
public int getAge() {...}
List<String> getEmailAddresses() {...}
Address getAddress() {...}
}
public class Address {
public String getStreet() {...}
public int getHouseNumber() {...}
public String getCity() {...}
public int getZIP() {...}
public String getState() {...}
}
Which may be serialized to:
{
"firstName": "John",
"lastName": "Doe",
"age": 42,
"emailAddresses": [
"john#doe.com",
"john.doe#somewhere.com"
],
"address": {
"street": "First Avenue",
"houseNumber": 123,
"city": "Smallville",
"ZIP": 12345,
"state": "CA"
}
}
I have configured in an Spring 3 application a ContentNegotiatingViewResolver so when I invoke a controller with a URL which looks like **.json it returns a json object using jackson library.
If I call this method:
#RequestMapping("/myURL.json")
public List<MyClass> myMethod(){
List<MyClass> mylist = myService.getList();
return mylist;
}
In the JSON I receive I have:
{"myClassList":[
{ object 1 in json },
{ object 2 in json },
{ object 3 in json } ...
]
}
my questions are: ¿is there any way to configure the name myClassList which is used in the json? ¿is it possible in this way a json without this variable (something like the following one)?
[
{ object 1 in json },
{ object 2 in json },
{ object 3 in json } ...
]
Thanks.
You can return a org.springframework.web.servlet.ModelAndView object, instead of a List object directly. On the modelAndView object you can set the name of the key. Please refer to the following snippet:
#RequestMapping("/myURL.json")
public ModelAndView myMethod(){
ModelAndView modelAndView = new ModelAndView();
List<MyClass> mylist = myService.getList();
modelAndView.addObject("MyClassName", myList);
return modelAndView;
}