Where to use converters? - json

I've just installed AndroidAnnotations and I want to use the #Rest annotation, however, as I read:
You MUST define converters field on this #Rest annotation, which
corresponds to the Spring HttpMessageConverters that will be provided
to the RestTemplate.
So, where to get MappingJackson2HttpMessageConverter? and how to install it?
Or at least, to convert my expected json string into a json object?
Is there any simple example?
Thanks

As it is written in the documentation, you have to add the Spring REST template dependency, which is the underlying REST library, AA is just a wrapper around it.
You can do it by adding this to your build.gradle.
dependencies {
compile 'org.springframework.android:spring-android-rest-template:2.0.0.M3'
} repositories {
maven {
url 'https://repo.spring.io/libs-milestone'
}
}
Now you can add any converter, like it is outlined in the doc:
#Rest(converters = { MappingJackson2HttpMessageConverter.class })
public interface MyRestClient {
#Get("/events")
EventList getEvents();
}

Related

Import XSD to OpenAPI

I have some model definition inside a XSD file and I need to reference these models from an OpenApi definition. Manually remodeling is no option since the file is too large, and I need to put it into a build system, so that if the XSD is changed, I can regenerate the models/schemas for OpenApi.
What I tried and what nearly worked is using xsd2json and then converting it with the node module json-schema-to-openapi. However xsd2json is dropping some of the complexElement models. For example "$ref": "#/definitions/tns:ContentNode" is used inside of one model as the child type but there is no definition for ContentNode in the schema, where when I look into the XSD, there is a complexElement definition for ContentNode.
Another approach which I haven't tried yet but seems a bit excessive to me is using xjb to generate Java models from the XSD and then using JacksonSchema to generate the json schema.
Is there any established library or way, to use XSD in OpenApi?
I ended up implementing the second approach using jaxb to convert the XSD to java models and then using Jackson to write the schemas to files.
Gradle:
plugins {
id 'java'
id 'application'
}
group 'foo'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-jsonSchema', version: '2.9.8'
}
configurations {
jaxb
}
dependencies {
jaxb (
'com.sun.xml.bind:jaxb-xjc:2.2.7',
'com.sun.xml.bind:jaxb-impl:2.2.7'
)
}
application {
mainClassName = 'foo.bar.Main'
}
task runConverter(type: JavaExec, group: 'application') {
classpath = sourceSets.main.runtimeClasspath
main = 'foo.bar.Main'
}
task jaxb {
System.setProperty('javax.xml.accessExternalSchema', 'all')
def jaxbTargetDir = file("src/main/java")
doLast {
jaxbTargetDir.mkdirs()
ant.taskdef(
name: 'xjc',
classname: 'com.sun.tools.xjc.XJCTask',
classpath: configurations.jaxb.asPath
)
ant.jaxbTargetDir = jaxbTargetDir
ant.xjc(
destdir: '${jaxbTargetDir}',
package: 'foo.bar.model',
schema: 'src/main/resources/crs.xsd'
)
}
}
compileJava.dependsOn jaxb
With a converter main class, that does something along the lines of:
package foo.bar;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
import foo.bar.model.Documents;
public class Main {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
try {
JsonSchema schema = schemaGen.generateSchema(Documents.class);
System.out.print(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema));
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
It is still not perfect though,... this would need to iterate over all the model classes and generate a file with the schema. Also it doesn't use references, if a class has a member of another class, the schema is printed inline instead of referencing. This requires a bit more customization with the SchemaFactoryWrapper but can be done.
The problem you have is that you are applying inference tooling over a multi-step conversion. As you have found, inference tooling is inherently fussy and will not work in all situations. It's kind of like playing Chinese whispers - every step of the chain is potentially lossy, so what you get out the other end may be garbled.
Based on the alternative approach you suggest, I would suggest a similar solution:
OpenAPI is, rather obviously, an API definition standard. It should be possible for you to take a code first approach, composing your API operations in code and exposing the types generated from XJB. Then you can use Apiee and its annotations to generate the OpenAPI definition. This assumes you are using JAX-RS for your API.
This is still a two-step process, but one with a higher chance of success. The benefit here is that your first step, inferring your XSD types into java types, will hopefully have very little (if any) impact on the code which defines your API operations. Although there will still be a manual step (updating the models) the OpenAPI definition will update automatically once the code has been rebuilt.

TypeScript: how to JSON stringify a class definition?

Say we have:
class MyClass {
myProperty: string
}
Is there any built in function or easy way to get JSON like this?:
{
"myProperty": "string"
}
EDIT: My end goal is I want to dynamically print typed class definitions to a web view, in some kind of structured object syntax like JSON. I'm trying to make a server API that will return the schema for various custom classes - for example http://myserver.com/MyClass should return MyClass's properties and their types as a JSON string or other structured representation.
Evert is correct, however a workaround can look like this
class MyClass {
myProperty: string = 'string'
}
JSON.stringify(new MyClass) // shows what you want
In other words, setting a default property value lets TS compile properties to JS
If the above solution is not acceptable, then I would suggest you parsing TS files with your classes with https://dsherret.github.io/ts-simple-ast/.
Typescript class properties exist at build-time only. They are removed from your source after compiling to .js. As such, there is no run-time way to get to the class properties.
Your code snippet compiles to:
var MyClass = /** #class */ (function () {
function MyClass() {
}
return MyClass;
}());
As you can see, the property disappeared.
Based on your update, I had this exact problem. This is how I solved it.
My JSON-based API uses json-schema across the board for type validation, and also exposes these schemas for clients to re-use.
I used an npm package to automatically convert json-schema to Typescript.
This works brilliantly.

SpringBatch - how to set up via java config the JsonLineMapper for reading a simple json file

How to change from "setLineTokenizer(new DelimitedLineTokenizer()...)" to "JsonLineMapper" in the first code below? Basicaly, it is working with csv but I want to change it to read a simple json file. I found some threads here asking about complex json but this is not my case. Firstly I thought that I should use a very diferent approach from csv way, but after I read SBiAch05sample.pdf (see the link and snippet at the bottom), I understood that FlatFileItemReader can be used to read json format.
In almost similiar question, I can guess that I am not in the wrong direction. Please, I am trying to find the simplest but elegant and recommended way for fixing this snippet code. So, the wrapper below, unless I am really obligated to work this way, seems to go further. Additionally, the wrapper seems to me more Java 6 style than my tentative which takes advantage of anonimous method from Java 7 (as far as I can judge from studies). Please, any advise is higly appreciated.
//My Code
#Bean
#StepScope
public FlatFileItemReader<Message> reader() {
log.info("ItemReader >>");
FlatFileItemReader<Message> reader = new FlatFileItemReader<Message>();
reader.setResource(new ClassPathResource("test_json.js"));
reader.setLineMapper(new DefaultLineMapper<Message>() {
{
setLineTokenizer(new DelimitedLineTokenizer() {
{
setNames(new String[] { "field1", "field2"...
//Sample using a wrapper
http://www.manning.com/templier/SBiAch05sample.pdf
import org.springframework.batch.item.file.LineMapper;
import org.springframework.batch.item.file.mapping.JsonLineMapper;
import com.manning.sbia.ch05.Product;
public class WrappedJsonLineMapper implements LineMapper<Product> {
private JsonLineMapper delegate;
public Product mapLine(String line, int lineNumber) throws Exception {
Map<String,Object> productAsMap
= delegate.mapLine(line, lineNumber);
Product product = new Product();
product.setId((String)productAsMap.get("id"));
product.setName((String)productAsMap.get("name"));
product.setDescription((String)productAsMap.get("description"));
product.setPrice(new Float((Double)productAsMap.get("price")));
return product;
}
public void setDelegate(JsonLineMapper delegate) {
this.delegate = delegate;
}
}
Really you have two options for parsing JSON within a Spring Batch job:
Don't create a LineMapper, create a LineTokenizer. Spring Batch's DefaultLineMapper breaks up the parsing of a record into two phases, parsing the record and mapping the result to an object. The fact that the incoming data is JSON vs a CSV only impacts the parsing piece (which is handled by the LineTokenizer). That being said, you'd have to write your own LineTokenizer to parse the JSON into a FieldSet.
Use the provided JsonLineMapper. Spring Batch provides a LineMapper implementation that uses Jackson to deserialize JSON objects into java objects.
In either case, you can't map a LineMapper to a LineTokenizer as they accomplish two different things.

Does Spring Support JSON Configuration?

Does anyone know if Spring has any extensions that allow for configuring its ApplicationContext via JSON (or really any other format) rather than XML? I couldn't find anything in the official docs, but I was wondering if there were any other open source extensions that could allow this.
Just to be clear, I'm not talking about configuring SpringMVC to set up a RESTful JSON-based web service or anything like that, just if it's possible to do Spring app configuration via JSON instead of XML.
As far as I know there is no project to support JSON as configuration source. It should be relatively easy to kick-start, (Spring container has no dependency on XML, it is just a way to construct bean definitions). However it is much more work than you might think.
Note that Spring provides xml-schema to assist you in writing correct XML. You won't get that much in JSON. Also many DSLs were built on top of Spring XML and custom namespaces support (spring-integration, mule-esb and others use it).
If you hate XML (many do), try out Java Configuration, available since 3.0 and improved in 3.1:
#Configuration
public class MyBeans {
#Bean
public Foo foo() {
return new Foo();
}
#Bean
public Bar bar() {
return new Bar(foo());
}
#Bean
public Buzz buzz() {
Buzz buzz = new Buzz();
buzz.setFoo(foo());
return buzz;
}
}
Interesting fact: thanks to some fancy proxying, foo() is called exactly once here, even though referenced twice.
Try JSConf library available on maven central, it's support Properties, HOCON and JSON format.
You can inject values from external file to your service and more !
Sample usage of JavaConfig :
You data stored on file app.conf
{
"root":{
"simpleConf":{
"url":"Hello World",
"port":12,
"aMap":{
"key1":"value1",
"key2":"value2"
},
"aList":[
"value1",
"value2"
]
}}
You service where your configuration must be inject
#Service("service")
public class Service {
#Autowired
private ConfigBean configBean;
}
Declare a interface to access your configuration values from your service
#ConfigurationProperties("root/simpleConf")
public interface ConfigBean {
String getUrl();
int getPort();
Map getAMap();
List getAList();
}
And your Spring configuration bean :
#Configuration
public class ContextConfiguration {
#Bean
public static ConfigurationFactory configurationFactory() {
return new ConfigurationFactory().withResourceName("app.conf") //
.withScanPackage("org.jsconf.core.sample.bean");
}
}

Why is this groovy code throwing a MultipleCompilationErrorsException?

I have the following groovy code :
class FileWalker {
private String dir
public static void onEachFile(String dir,IAction ia) {
new File(dir).eachFileRecurse {
ia.perform(it)
}
}
}
walker = new FileWalker()
walker.onEachFile(args[0],new PrintAction())
I noticed that if I place a def in front of walker , the script works. Shouldn't this work the way it is now ?
You don't need a def in groovyConsole or in a groovy script. I consider it good programming practice to have it, but the language will work without it and add those types of variables to the scripts binding.
I'm not sure about the rest of your code (as it won't compile as you've posted it). But you either have a really old version of groovy or something else is wrong with your config or the rest of your code.
With the addition of a stub for the missing IAction interface and PrintAction class, I'm able to get it to run without modification:
interface IAction {
def perform(obj)
}
class PrintAction implements IAction{
def perform(obj) {
println obj
}
}
class FileWalker {
private String dir
public static void onEachFile(String dir,IAction ia) {
new File(dir).eachFileRecurse {
ia.perform(it)
}
}
}
walker = new FileWalker()
walker.onEachFile(args[0],new PrintAction())
I created a dummy directory with "foo/bar" and "foo/baz" files.
If I save it to "walkFiles.groovy" and call it from the command line with
groovy walkFiles.groovy foo
It prints:
foo/bar
foo/baz
This is with the latest version of groovy:
groovy -v
Groovy Version: 1.6-RC-3 JVM: 1.5.0_16
In scripting mode (or via "groovyConsole"), you need a declaration of walker with "def" before using it. A Groovy script file is translated into a derivative class of class Script before it get compiled. So, every declaration needs to be done properly.
On the other hand, when you're running a script in "groovysh" (or using an instance of class GroovyShell), its mechanism automatically binds every referencing object without the need of declaration.
updated:
My above answer would be wrong as I decompiled a .class of Groovy and found that it's using a binding object inside the script as well. Thus my first paragraph was indeed wrong.