I have a spring rest API that returns a JSON response from the response class shown below:
public class myResponse {
private String anyString;
private boolean isBoolean;
//getters and setters
}
I am expecting the JSON response to be:
{
"anyString" : "foo",
"isBoolean" : true
}
However, whenever I inspect the browser for the response obtained, I get:
{
"anyString" : "foo",
"boolean" : true
}
Why is the preceding "is" being truncated?
If you're using Spring Boot, then somewhere internally it uses Jackson to transform your object into json string.
you can dive into the logic of ObjectMapper class, but the idea is that it follows JavaBeans convention for accessing fields and getting resulting naming.
So, for boolean property named 'isSth' (via method object.isSth() ) actually represents a field 'sth' for json. If you want to strictly set the name of the field in json, use #JsonProperty annotation
Related
I have nested complex object in my controller:
class ClientDTO {
public InnerClass cl;
public getCl()...
public setCl()...
}
InnerClass contains some primitive data types Integer,String.
My controller just returns this ClientDTO.
On my thymeleaf template I've got :
var client=[[${client}]]
Here client is a ClientDTO value, returned from the controller.
This variable client is serialized into ru.foo.ClientDTO#6543785
which is incorrect.
How can I fix it to receive correct client object in form of json like this: ClientDTO{cl: {....}} ?
It's hard to say where exactly you want this based on your description, but I am assuming your var definition is in a script tag. If so, use
<script data-th-inline="javascript">
to make thymeleaf properly create the variable. Secondly, wrap client like this:
var client = /*[[${client}]]*/ {};
to ensure there is a default and preserve natural templating, with the default being {} or '' or such. From there you can convert to json if you wish.
I have a Spring Boot app using Jackson. I'm not using Jersey just regular Spring MVC. I have a Wrapper Request class:
public class WrapperRequest {
#NotNull
private final Object obj; // some object that corresponds with a JSON object
#JsonCreator
public WrapperRequest(#JsonProperty("wrapper") final Object obj) {
this.obj = obj;
}
public Object getObj() {return obj}
}
The JSON for this would look like:
{
"wrapper":{
//Object data
}
}
The #NotNull from javax isn't working as I excepted. The way I want it to work is that if the consumer sends in a JSON that have a typo like:
{
"wrapperr":{
//Object data
}
}
Jackson will not map my wrapper class because the key in the JSON doesnt match the JsonProperty i.e ("wrapper") (so Object will be null and then I will get NPE later on if I tried to interact with Object. Am I using Jackson wrong? i.e Jackson maps things that it knows about and the rest is null or am I not using the #NotNull annotation correctly?
Jackson is not aware of Bean Validation annotations like #NotNull. For the specific case of "null", you can mark the constructor parameter as #JsonProperty(required = true). More generally, you can use #NotNull on a property as you did and mark your MVC controller parameter with #Valid (which will not cause deserialization to fail but will cause Spring MVC to return a 400 if the validation fails).
Note that you may also be interested in the UNWRAP_ROOT_VALUE feature, which would allow you to eliminate the need for the wrapper class in this particular case.
I'm using JAX-RS and Dropwizard to develop an API (I'm pretty new to both)
I want to have a json field called isInNetwork for example. But the strange thing for me is after defining the model and resource, I see inNetwork as the defined json field. (the is prefix is removed)
to be more specific when I define the model as:
#JsonProperty
private Boolean isInNetwork;
and when I run the server I see "inNetwork": false
wanted to know if that's something by default (that I'm not aware of) set by dropwizard / jax-rs for Booleans?
Don't use "is" prefix for the field at all, because of "is" prefix is used for getters for boolean fields. getIsInNetwork method name looks bad.
Better to specify JSON property name for the field
#JsonProperty("isInNetwork")
private Boolean inNetwork;
public Boolean isInNetwork() {
return inNetwork;
}
public void setInNetwork(Boolean inNetwork) {
return this.inNetwork = inNetwork;
}
I created a class from a json template with http://www.jsonschema2pojo.org/ and I use Genson to map my json with a Jersey based WS.
This is the first lines of my "json class" :
#JsonPropertyOrder({
"public_key",
"template",
"signature",
"due_date",
"fulfillment_date",
"template_lang_code",
"clients_id",
"electronic_invoice",
"is_draft",
"recurring_time",
"comment",
"currency",
"items",
"payment_method",
"ts"
})
public class CreateInvoiceBean {
...
...
I have getters and setters also in my class too.
I have created a restfull Ws to handle post requests and i tried to send jsons object with firefox RESTClinent plugin.
This is the first lines of my json object that i tried to send:
{
"public_key": "7f566499549fc9e6d9cc69ca3b10d5f5",
"template": "billingo",
"signature": "9273882e8b3bc7f57e1ef3bc10041bc4bf9d835c152a1e0b810b77b3d51864ad",
"due_date": "2015-10-30",
...
...}
My WS Post handler method looks like this:
#POST
#Path("/invoice")
#Consumes("application/json")
#Produces("application/json")
public String createInvoice(CreateInvoiceBean newBillingoInvoice) {
LOG.info("invoicenum:. " + newBillingoInvoice.getDueDate());
return newBillingoInvoice.getDueDate();
}
My request arrives, and the createInvoice() method invoked but if I call newBillingoInvoice.getDueDate() it's return null, but when I call newBillingoInvoice.getSignature() it's returning with the value that I sent in the request json.. And so on.. if I call newBillingoInvoice.getXY(); returns null and if I call newBillingoInvoice.getOtherSomething(); return with value.. etc..
My question is, how could it happen that one property is null and the other is not null in the same object? When I create the request I set all properties no one of them was null.
Please help me!
Thank you!
It is due to the name I think. In your json we can see that you use underscore insead of upper case at word boundaries. Like due_date instead of dueDate. And I suppose that the properties in your code follow the usual java naming convetion with upper case.
One solution would be to annotate with #JsonProperty those set and get methods to change the name from "dueDate" to "due_date".
BTW the generated code is not for Genson, JsonPropertyOrder isn't a Genson annotation.
I'm trying out apache-camel, and I've set up a basic route that calls an http service via http4 component, transforms the result via unmarshal().json(JsonLibrary.Jackson), and then prints out part of the response in a bean component.
The problem I'm having is that it blows up at runtime when it gets to the json unmarhsaller:
No type converter available to convert from type: java.util.HashMap to the required type: com.xxx.MyType
The response is of this format:
{"data":[{"x":"y"},{"x":"z"}]}
And my object model is like:
#lombok.Data
class Response {
private List<Elem> data;
}
#lombok.Data
class Elem {
private String x;
}
So it would appear that the unmarshaller thinks the response is a hash map, whereas I want it to unmarshal into an object structure. Is there a way to get it to do what I want?
Found the answer, posting in case anyone else runs into this. The route builder should be setup like:
from("direct:start").to("http4://...").unmarshal().json(JsonLibrary.Jackson,com.xxx.Response)
.to("bean:com.xxx.MyResponseEchoer")
I.e. pass the class type to the json method.