Solution for Generic in Go - json

I want to make a useful library for JSON responses. In Java I've this already. I started now new with Go and have no idea how to transform my Java code. I've read that Go doesn't have anything like generics, but how can I solve my problem?
I'm talking about the following part of code:
#Data
public class ServiceResult<T extends Serializable> implements Serializable {
private ServiceResultStatus status;
private String type;
private T content;
private String hash;
private String destination;
private HashMap<String, Metadata> metadata = new HashMap<>();
...
The idea of service-result is to provide an structural pattern for RESTful web services. If you need more information, here is the link to my repo on Github: https://github.com/Viascom/service-result
A service-result looks at the end like this:
{
"status": "successful",
"type": "ch.viascom.example.models.response.GetTasksResponse",
"content": [
{
"id": "3e99c7fb-0ed7-11e7-a7a5-0050569c3e5a",
"name": "Example Task"
}
],
"hash": "7bf9c04d1e9f8fe7995e4b8beeac1a4c830e7ea",
"destination": "ch.viascom.example.handler.TaskHandler",
"metadata": {
}
}

You can add the json-mapping directly to the structure definition and use the encoder, decoder to marshal and unmarshal it. It's all built in and easier than in other languages, imho.
type ServiceResponse struct {
Value string`json:"nameInJsonResponse"`
}
here is a good example from the playground: https://play.golang.org/p/4L2wMVv7tW
For your particular case it should be something like this:
type ServiceResult struct {
Status ServiceResultStatus`json:"status"`
Type string`json:"type"`
Hash string`json:"hash"`
Destination string`json:"destination"`
Metadata map[string]Metadata metadata`json:"metadata"`
}
type ExplizitServiceResult struct {
ServiceResult
Content SomeStruct`json:"content"`
}
https://play.golang.org/p/FFfiq6LxVt
If you don't want to derive every user struct from the ServiceResult you can define the content as interface{} so every struct can be inserted. I've updated my example for this. Maybe this is the easiest solution to your problem.
https://play.golang.org/p/LNgreqrnnw

Related

Spring Rest: Mapping a property of a bean as nested JSON

My Spring REST controller needs to map an object parameter that looks like this:
{
"batchId": 43091,
"domain": "XX",
"code": "XXX",
"effectiveDate": "2020-02-13",
"status": "Y",
"result": [{"ruleName":"name",...]}]
}
I'm having trouble coming up with the DTO to convert this data into. What I have so far looks like this:
#Data
#NoArgsConstructor
#EqualsAndHashCode
public class ValidationResult {
private String result;
private String status;
private String batchId;
private String domain;
private String code;
private String effectiveDate;
}
But result, which contains the embedded JSON, is always null. I don't care about that JSON being mapped, as I'm storing it as a JSON type in the database (Postgresql). But what Java type do I need to declare it to be to get the controller to convert it? I tried making it a javax.json.JsonObject, but that failed.
What we always do with those json inputs is to map those to specific classes. Which means, in your case, result could be a class which itself contains the given fields "ruleName" and their types. Then your Validaton Result containts a private Result result. If naming conventions are quite right the used mapper will be able to convert and map the response to the class and its properties.

jackson/json using List<String[]> and data binding

I have been using Jackson (which works great BTW) for all the json "tree" that I am traversing until I get to the deepest json level where unfortunately the json properties are "dynamic" such as the below so it does not make sense to create objects for those...
"values": [
{
"duration": 0.20669677067008357
},
{
"weight": 0.013746673955838557
}
]
The issue is that "duration" and "weight" are dynamic so I was hoping to use List<String[]> for 'values' but I don't think that it is possible. For example, the next call could have "duration", "weight", and "marketValue" or 10 other properties.
Any suggestions on how to approach this problem?
I actually found a solution for those interested:
This article/how to was very helpful in understanding the jackson data-binding flexibility:
http://www.studytrails.com/java/json/java-jackson-Annotations-Dynamic-Beans.jsp
Particularly, I chose to use the annotation #JsonAnySetter such as this on my POJO:
private String name;
private Object value;
#JsonAnySetter
public void set(String name, Object value) {
this.name = name;
this.value = value;
}
I then opted to place those name/value pairs into a Map<String, Object> for easy retrieval... Works great!

Add 'standard' JSON fields to serialized objects in REST API

Motivated by this: Google JSON Style Guide, I want to insert a bit of custom serialization logic to my rest API. I'm using the WebAPI 2 and JSON.NET. My goal is to wrap the 'payload' of my response in the 'data' field of the main JSON response, as described in the style guide, include an apiVersion field in every response, and that sort of thing. Of course the controller actions just return straight POCO's, and I want to modify the container that they're sent inside of, not the POCOs themselves, so:
{
"id": "111",
"apiVersion": "1.0",
"data": {
"kind": "monkey",
"name": "manny",
"age": "3"
},
"error": null
}
...that type of thing. So I envision inserting little bits of standard data into every response before it goes over the wire. What's the best way to accomplish this?
TIA.
I believe you can use an ActionFilterAttribute to achieve this kind of behaviour. You would first need to create a class to represent your wrapped response (all the properties are string, adjust as you need):
public class WrappedJsonResponse
{
public string Id {get;set;}
public string ApiVersion {get;set;}
public object Data {get;set;}
public string Error {get;set;}
}
The ActionFilterAttribute allow you to do some processing after the execution of an action via the virtual OnActionExecuted method:
public class WrappedJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext context)
{
// A POCO response will normally be wrapped in an ObjectContent
var content = context.Response.Content as ObjectContent
if(content != null)
{
// Create the WrappedJsonResponse object appropriately and
// put the original result in the Data property
content.Value = new WrappedJsonResponse { Data = content.Value };
content.ObjectType = typeof(WrappedJsonResponse);
}
}
}
With the attribute, you can then choose to apply it where you want (whole controller, action only or as a default filter).
Note: I do not have access to a development environment at the moment and have not tested the filter. If this is not complete, it should at least give you an idea on how it can be done.

Strange Mapping Behaviour Jackson JSON

I've got a strange mapping Issue with Jackson on Android.
I've got a "Content" Class which should be used by the Jackson Mapper.
It looks like this:
public class content {
private String header;
private String subheader;
private String bodytext;
#JsonProperty("singleimage")
private String image;
#JsonProperty("uid")
private String id;
#JsonProperty("link")
private String article;
#JsonProperty("CType")
private String cType;
// Eclipse auto generated getters & setters
...
}
The corresponding JSON Object looks like this:
{
"header": "xyz",
"subheader": "abc",
"bodytext": "abc",
"singleimage": "abc",
"images": "abc.jpg",
"teaser_elements": "",
"uid": "13",
"link": "xyz.htm",
"CType": "row_header"
}
Now when I use the Jackson Maper to create instances of Content from a provided JSON all fields of the content class get populated correctly - all except "cType".
I already tried to move the #JsonProperty("CType") annotation to the setCType Method but still no effect.
I don't get any Exceptions while mapping the class or anything else and as it seems to me that all mappings pretty much do the same (mapping to String) im kinda buffled why it doesn't work wit the "CType".
Any suggestions what the problem might be are highly appreciated.

Jackson JSON to Java mapping for same attrubute with different data type

I have a JSON object which I don't have control of and want to map it to a Java object which is pre-created.
There is one attribute in the JSON object which can be a URL or it could be a JSONArray.
Class SomeClass {
private URL items;
public URL getURL() {
return items;
}
public void setURL(URL url) {
this.items = url;
}
}
Below is the JSON:
Case A:
{
...
items: http://someurl.abc.com/linktoitems,
...
}
OR
Case B
{
...
items: [
{ "id": id1, "name": name1 },
{ "id": id2, "name": name2 }
]
...
}
If i create the POJO to map for Case A, Case B fails and vice versa. In short, is there a way to map the JSON attribute to the POJO field with different data types? In that case I will create two separate fields in the POJO named,
private URL itemLink;
private Item[] itemList;
It depends on exact details, but if what you are asking is if it is possible to map either JSON String or JSON array into a Java property, yes this can be done.
Obvious way would be to define a custom deserializer which handles both kinds of JSON input.
But it is also possible to define Java type in such a way that it can be constructed both by setting properties (which works from JSON Object) and have a single-String-arg constructor or static single-String-arg factory method marked with #JsonCreator.
Yet another possibility is to use an intermediate type that can deserialized from any JSON: both java.lang.Object and JsonNode ("JSON tree") instances can be created from any JSON. From this value you would need to do manual conversion; most likely in setter, like so:
public void setItems(JsonNode treeRoot) { .... }
What will not work, however, is defining two properties with the same name.
One thing I don't quite follow is how you would convert from List to URL though. So maybe you actually do need two separate internal fields; and setter would just assign to one of those (and getter would return value of just one).