I have a json webservice I'm calling with a spring rest template. One of the request parameters is an interface. I'm looking for the right combination of annotations (either Jackson or Jaxb) that will create my json request.
My request needs to look like this:
{
"request": {
"specificAccountIdentifier": {
"field1" : "value",
"field2" : "value"
}
}
}
However, right now, it's marshaling as this:
{
"request": {
"accountIdentifier": {
"field1" : "value",
"field2" : "value"
}
}
}
Request Class:
#XmlRootElement
#XmlType
#XmlAccessorType(XmlAccessType.FIELD)
public class Request {
#XmlAnyElement
#XmlElementRefs({#XmlElementRef(type = SpecificAccountIdentifier.class)})
private AccountIdentifier accountIdentifier;
public Request() {
}
}
AccountIdentifier:
#XmlSeeAlso(SpecificAccountIdentifier.class)
public interface AccountIdentifier extends Serializable {
}
SpecificAccountIdentifier:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement
#XmlType
public class SpecificAccountIdentifier implements AccountIdentifier {
private static final long serialVersionUID = 8894475816041559L;
private Long field1;
private Long field2;
...class details...
}
I've tried a few different combinations of #JsonTypeInfo, but can't get anything to work right.
UPDATE:
Even after looking into the answer below, I still could not get anything to work, so I ended up just writing my own custom Serializer.
Found similar question asked 4 years ago but it seems you can use it to kick start the idea behind.
Basically it is using EclipseLink JAXB (MOXy) and a factory method to generate the Implementation of your interface.
https://stackoverflow.com/a/16155520/6039974
Related
Today I have found a problem which I need some advice from you.
I have a model from Frontend application which sends me some Json structure. It uses camelCase.
Then I need to send the same model to another service to trigger some functionality but there is a different Json name convention. It basically uses underscore notation instead of camel case but also there some other random differences so I would not say it is strict underscore.
And here's a problem. When I serialize Json from Frontend, is there a better way to remap those field names instead of creating duplicated model but with different JsonProperty annotation? I would like to avoid this solution because model contains around 15 classes so I would say it's big.
Another solution I was thinking about is JSONATA expression. What do you think?
#Data
#NoArgsConstructor
#AllArgsConstructor
public class ADLayout {
private String firstName;
private LayoutHeader layoutHeader;
private Long projectId;
private List<Worksheet> worksheets;
}
#Data
#NoArgsConstructor
#AllArgsConstructor
public class ADLayoutAnotherService {
#JsonProperty("first_name")
private String firstName;
#JsonProperty("layout_header")
private LayoutHeader layoutHeader;
#JsonProperty("project_id")
private Long projectId;
private List<Worksheet> worksheets;
}
FRONT Model
{
"firstName": "test",
"projectId": 5,
"worksheets": [
{
"sheetUid": "201f1630-c97d-4fec-89b4-7b45b44bcebc",
"sheetHeader": {
"requestedData": "",
"instructions": ""
}
}
]
}
Another service Model
{
"first_name": "test",
"project_id": 5,
"worksheets": [
{
"sheet_uid": "201f1630-c97d-4fec-89b4-7b45b44bcebc",
"sheet_header": {
"requested_data": "",
"INSTRUCTIONS": ""
}
}
]
}
Important thing is that the model sent from Frontend is also stored in database and returned to frontend so #JsonAlias will not work here
I am implementing a REST server using Spring Boot, JAXB2 and Jackson. This server supports JSON and XML and it is based on official specifications.
I am currently having a serialization problem specific to the JSON format and I do not know how it can be solved?
The specification defines several primitive types as string, integer, etc. that can be extended and depending of this extension, the result of the serialization is not the same.
The Java classes
public class PrimitiveType {
#XmlAttribute
private String id
#XmlElement(name = "extension")
private List<Extension> extensions = new ArrayList<>();
// Getters and Setters
}
public class StringType extends PrimitiveType {
#XmlAttribute
private String value;
// Getter and Setter
}
JSON
// Without id and/or extension(s)
"code" : "abc"
// With id and/or extension(s)
"code ": "abc",
"_code": {
"id": "1",
"extension" : [ {
"url" : "http://mydomain/ext/1",
"valueString" : "abc-1"
}]
}
I do not have any problem with the XML but it is not the same for the JSON. I do not know how I can add a property dynamically on the same level. I had a look on the JsonSerializer but it seems that it allows to change the serialization on the object itself.
Does anyone had a chance to do this kind of things before?
I have a pojo class.
#XmlRootElement(name = "project")
public class Project {
private UUID id;
private String label;
private String name;
//getters and setters
}
It accepts this as input if I try from postman.
{
"label" : "label",
"name" : "name"
}
But, I want it to accept values as
{
"project" : {
"label" : "label",
"name" : "name"
}
}
My endpoint method is
#POST
#Consumes(MediaType.APPLICATION_JSON)
#Produces(MediaType.APPLICATION_JSON)
public Response createProject(Project project) {
log.info("createProject called." + project);
if (project == null) {
return Response.ok(false).build();
}
ps = new ProjectServiceImpl();
return Response.ok(ps.createProject(project)).build();
}
There are various other methods which are like this, like get all projects, where other party expects 'root-name' or 'class-name' like this at the start of json. I am stuck with things like this and it's slowing down my work. Please suggest me something or provide any source where I can read the stuff.
I think SerializationFeature.WRAP_ROOT_VALUE and DeserializationFeature.UNWRAP_ROOT_VALUE are configuration options that you are looking for.
Read more here:
https://github.com/FasterXML/jackson-databind/wiki/Serialization-Features
https://github.com/FasterXML/jackson-databind/wiki/Deserialization-Features
Please use #XmlRootElement instead of #XmlRootElement(name = "project") and try it out
A good read if you are using spring and consuming a rest service - http://spring.io/guides/gs/consuming-rest/
I am new to Java RESTful web services. I have classes structure as following:
class BaseClass{
String basicInfo;
}
class DataClass extends BaseClass{
String id;
}
class DataList extends BaseClass{
List<DataClass> dataList;
}
when I get DataList class as Response of web-service, I get it in following format:
{
"basicInfo" : "Mandetory",
"dataList" : [
{
"basicInfo" : "Optional",
"id" : "I_1001"
},
{
"basicInfo" : "Mandetory",
"id" : "I_1002"
}
]
}
But I want to ignore "basicInfo" attribute in every Data Object of dataList.
ex.
{
"basicInfo" : "Mandetory",
"dataList" : [
{
"id" : "I_1001"
},
{
"id" : "I_1002"
}
]
}
Is there any way through which I could ignore these attributes(using annotations)?
Note : I can't change the class structures.
#JsonIgnore
the above is the annotation you require. for more variations of this you can go through the following link. add the above annotation to the fields which you wish to ignore in your transfer object and it will be ignore when parsing. Since you haven't mentioned which library you are using to work with json, i have answered your question using Jackson Library.
You can use JAX-B annotation #XmlTransient on your attribute basicInfo.
Alternatively, when JSON-B (JSR 367) will be available (Java EE 8), you can use the #JsonbTransient or, even better, the #JsonbVisibility attribute.
Let's say I have Java classes that looks like this:
public class A {
public String name;
public B b;
}
public class B {
public int foo;
public String bar;
}
I want to serialize an instance of A into JSON. I am going to use the ObjectMapper class from Jackson:
A a = new A(...);
String json = new ObjectMapper().writeValueAsString(a);
Using this code, my JSON would look like this:
{
"name": "MyExample",
"b": {
"foo": 1,
"bar": "something"
}
}
Instead, I want to annotate my Java classes so that the generated JSON will instead look like this:
{
"name", "MyExample",
"foo": 1,
"bar": "something"
}
Any ideas?
Personally I think you may be better off mapping structure to structure, and not doing additional transformations.
But if you do want to go with the plan, just use Jackson 2.x, and add #JsonUnwrapped annotation on property b. That should do the trick.