I would like to deal with JSON that can be either:
{
"data": {
"id": "1",
"type": "permissions",
"attributes": { "permission": "VIEW" }
"relationships": {
"user": { "data": { "id": "U1", "type": "users" } }
"resource": { "data": { "id": "G1", "type": "groups" } }
}
}
}
OR
{
"data": {
"id": "1",
"type": "permissions",
"attributes": { "permission": "VIEW" }
"relationships": {
"user": { "data": { "id": "U1", "type": "users" } }
"resource": { "data": { "id": "P1", "type": "pages" } }
}
}
}
That is, I would like the "resource" relationship type to be entirely customizable ("groups" or "pages" or anything else).
Is there a way to do that with Katharsis? I was hoping for some kind of inheritance...
#JsonApiResource(type = "permissions")
public class Permission {
...
#JsonApiToOne
private SharedResource resource;
...
}
public interface SharedResource {
...
}
#JsonApiResource(type = "pages")
public class Page implements SharedResource {
...
}
But that doesn't work completely. I've finagled it enough where a findAll returns pretty well (though the links don't reflect the type "pages"), but any POST with the relationships set returns a 405 Method Not Allowed.
Not sure it's possible, but I'd really like it to be since I like Katharsis.
I think what you're referring to is polymorphic entity types. If so, this has been asked for repeatedly but currently doesn't exist.
Related
I'm generating JsonSchema from Java class using fasterxml.jackson.
The generated Jsonschema will be as below
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
My code to generate JsonSchema
public static String getJsonSchema(Class definitionClass) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper().disable(
MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS);
JavaType javaType = mapper.getTypeFactory().constructType(definitionClass);
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
JsonSchema schema = schemaGen.generateSchema(javaType);
return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);
}
I tried to use ArraySchema arraySchema = schema.asArraySchema(); but it generates invalid schema.
My expected JsonSchema should be like below
{
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}
TL;DR: Call getJsonSchema(MyClass[].class)
Works fine if we simply tell it to generate the schema of a Java array.
To demo, I created a MyClass class fitting the shown schema. I used public fields for simplicity of the demo, but we'd use private fields and public getter/setter methods in real life.
class MyClass {
public String id;
public String name;
}
Now, to show that we get the same result as in the question, we call it with MyClass.class:
System.out.println(getJsonSchema(MyClass.class));
Output
{
"type" : "object",
"id" : "urn:jsonschema:MyClass",
"properties" : {
"id" : {
"type" : "string"
},
"name" : {
"type" : "string"
}
}
}
Now, we want the schema to be an array of those, so we will instead call it using MyClass[].class.
System.out.println(getJsonSchema(MyClass[].class));
Output
{
"type" : "array",
"items" : {
"type" : "object",
"id" : "urn:jsonschema:MyClass",
"properties" : {
"id" : {
"type" : "string"
},
"name" : {
"type" : "string"
}
}
}
}
The above was tested using jackson-module-jsonSchema-2.10.3.jar.
I have a basic Rest Controller which returns a list of models in json to the client:
#RestController
public class DataControllerREST {
#Autowired
private DataService dataService;
#GetMapping("/data")
public List<Data> getData() {
return dataService.list();
}
}
Which returns data in this format:
[
{
"id": 1,
"name": "data 1",
"description": "description 1",
"active": true,
"img": "path/to/img"
},
// etc ...
]
Thats great for starting, but i thought about returning data of this format:
[
"success": true,
"count": 12,
"data": [
{
"id": 1,
"name": "data 1",
"description": "description 1",
"active": true,
"img": "path/to/img"
},
{
"id": 2,
"name": "data 2",
"description": "description 2",
"active": true,
"img": "path/to/img"
},
]
// etc ...
]
But i am not sure about this issue as i can not return any class as JSON... anybody has suggestions or advices?
Greetings and thanks!
"as i can not return any class as JSON" - says who?
In fact, that's exactly what you should do. In this case, you will want to create an outer class that contains all of the fields that you want. It would look something like this:
public class DataResponse {
private Boolean success;
private Integer count;
private List<Data> data;
<relevant getters and setters>
}
And your service code would change to something like this:
#GetMapping("/data")
public DataResponse getData() {
List<Data> results = dataService.list();
DataResponse response = new DataResponse ();
response.setSuccess(true);
response.setCount(results.size());
response.setData(results);
return response;
}
I have a Class like so:
public class Wrapper<T>{
#JsonProperty
public Creds credentials;
public T data;
}
which, when serialized returns JSON like so:
{
"credentials" : {
"token": "xxxxx"
},
"data": {
"A": "3",
"Sub": {
"X": "something",
"Y": "something else"
}
}
}
I would like to move the contents of "data" up and return the JSON like so:
{
"credentials" : {
"token": "xxxxx"
},
"A": "3",
"Sub": {
"X": "something",
"Y": "something else"
}
}
Any pointers on how to achieve that? I've tried using the attribute below and overriding the toString on each Type of 'T', but that did not work.
#JsonSerialize(using = ToStringSerializer.class)
The solution was to add the following attribute to the "data" property.
#JsonUnwrapped
I'm trying to marshal a recursive bean to JSON with MOXy in Jersey, following the specification of RFC6901 aka JSON Pointer.
E.g., I'd like to marshal this:
public class Bean {
public Integer id;
public String name;
public Bean other;
public List<Bean> next;
}
x = new Bean(123, "X");
a = new Bean(456, "A");
x.other = a;
x.next.add(x);
x.next.add(a);
into this:
{
"id": 123,
"name": "X",
"a": { "id": 456, "name": "A", "next": [ ] },
"next": [
{ "$ref": "#" },
{ "$ref": "#/a" }
]
}
and then unmarshal this JSON to the original bean. Does someone have any suggestion/solution to this problem?
I'm programming one android list-detail application and I have to load app structure from json. I'm trying to deserialize non-optimal json with Gson (Java) to objects, from that I'm going to dynamically generate fragments (I hope it can be done :-) ).
I have tabs within main FragmentActivity and one tab has own fragment and own json. Every tabs has own fragmentstack for controlling with back and up button.
I have this json:
{
"data": [],
"children": [
{
"data": {
"id": "5",
"deep": "0",
"url": "compare",
"type": "navigation",
"name": "Vergleich",
"text": null,
"number": null
},
"children": [
{
"data": {
"id": "12",
"deep": "1",
"url": "information",
"type": "navigation",
"name": "information",
"text": null,
"number": null
},
"children": []
},
{
"data": {
"id": "13",
"deep": "1",
"url": "application",
"type": "navigation",
"name": "application",
"text": null,
"number": null
},
"children": []
}
]
}
]
}
and I created this classes for gson:
public class StructureItem {
StructureData data;
ArrayList<StructureItem> children;
}
public class StructureData {
public int id;
public int deep;
public String url;
public String type;
public String name;
public String text;
public String number;
}
I tried to create Object with:
String s = LoadJson();
Gson gson = gsonBuilder.create();
StructureItem root = gson.fromJson(s, StructureItem.class);
But cannot succeed.
How would you solve my problem? Any easy solution?
It would be awesome has some notes for this.
I'm programming for couple years, but this is my first android project. Quite monstrous framework!
Try to replace ArrayList<StructureItem> to StructureItem[] in class StructureItem.