I have an XML file, like
<stock><name>AXL</name><time>19-07</time><price>11.34</price></stock>
<stock><name>AIK</name><time>19-07</time><price>13.54</price></stock>
<stock><name>ALO</name><time>19-07</time><price>16.32</price></stock>
<stock><name>APO</name><time>19-07</time><price>13.56</price></stock>
...............more
How can I parse this into JSON structure file?
For a simple solution, I recommend Jackson, a Java library for generating and reading JSON with an extension for XML, as it can transform arbitrarily complex XML into JSON with just a few simple lines of code.
input.xml
<entries>
<stock><name>AXL</name><time>19-07</time><price>11.34</price></stock>
<stock><name>AIK</name><time>19-07</time><price>13.54</price></stock>
<stock><name>ALO</name><time>19-07</time><price>16.32</price></stock>
<stock><name>APO</name><time>19-07</time><price>13.56</price></stock>
</entries>
The Java Code:
import java.io.File;
import java.util.List;
import org.codehaus.jackson.map.ObjectMapper;
import com.fasterxml.jackson.xml.XmlMapper;
public class Foo
{
public static void main(String[] args) throws Exception
{
XmlMapper xmlMapper = new XmlMapper();
List entries = xmlMapper.readValue(new File("input.xml"), List.class);
ObjectMapper jsonMapper = new ObjectMapper();
String json = jsonMapper.writeValueAsString(entries);
System.out.println(json);
// [{"name":"AXL","time":"19-07","price":"11.34"},{"name":"AIK","time":"19-07","price":"13.54"},{"name":"ALO","time":"19-07","price":"16.32"},{"name":"APO","time":"19-07","price":"13.56"}]
}
}
This demo uses Jackson 1.7.7 (the newer 1.7.8 should also work), Jackson XML Databind 0.5.3 (not yet compatible with Jackson 1.8), and Stax2 3.1.1.
http://keithchadwick.wordpress.com/2009/03/14/converting-xml-to-json-with-xsl-part-2/
You haven't specified language... so... I haven't got more specific on it than to think "you already have XML, probably you have access to xsl/xslt":
http://www.w3.org/TR/xslt
http://www.thomasfrank.se/xml_to_json.html
Related
I am currently using KotlinModule class in my java file by importing import com.fasterxml.jackson.module.kotlin.KotlinModule;, but in recent jackson library upgrade (using 2.13) it is has been depricated. I was looking for the new convention, and came across this https://github.com/FasterXML/jackson-module-kotlin#usage
however I am not able to load the recommended functions in java file, i think that only works in Kotlin file. Is there an alternative?
This module uses Kotlin extension functions, they are all defined in an Extensions.kt file and as such are accessible by importing the ExtensionsKt class. For example :
import com.fasterxml.jackson.module.kotlin.ExtensionsKt;
import com.fasterxml.jackson.databind.ObjectMapper;
ObjectMapper mapper = ExtensionsKt.jacksonObjectMapper();
If the method extends a type, for example in Kotlin :
val mapper = ObjectMapper().registerKotlinModule()
The method is defined in kotlin as :
fun ObjectMapper.registerKotlinModule(): ObjectMapper
It will be converted in java to :
public static final ObjectMapper registerKotlinModule(#NotNull ObjectMapper $this$registerKotlinModule)
So to use it, you need to pass the extended type :
ObjectMapper mapper = ExtensionsKt.registerKotlinModule(new ObjectMapper());
I am writing a process that needs to pull JSON data from an API and provide it to another system that requires the field names to be completely lowercased. I have attempted to utilize the built in LowerCaseStrategy but this does not work. An example of what I have tried is:
package com.example
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategies;
public class Example {
private static final ObjectMapper mapper = new ObjectMapper();
public Example(){
mapper.setPropertyNamingStrategy(new PropertyNamingStrategies.LowerCaseStrategy());
}
public JsonNode fetchData(String url) throws MalformedURLException, IOException{
JsonNode data = mapper.readTree(new URL(url));
return data;
}
}
A PropertyNamingStrategy affects how JSON property names are mapped from methods and fields in a Java class. This code doesn't do any mapping to Java objects, it only deserializes JSON into a JsonNode. In that case, PropertyNamingStrategy doesn't apply, and the names are retained from the original JSON source.
I was able to find the following gist which is working for me https://gist.github.com/stmcallister/92d0b4c2355a490ffed008cfbda69063
There's probably a better solution out there but this is perfect for my use case.
How to set representation for specific format on Json Serializer used by MicroProfile Rest Client?
I have a service that requires a year-month input, formated as ISO 8601 "YYYY-MM". The server-side is working, and the response is correctly formatted, but implementation is Resteasy.
I'm using MicroProfile Rest Client, and entity attribute is defined as java.util.YearMonth.
The request is sent with serialized JSON year-month attribute represented as an object when I want it to be a formatted string.
Already tried annotating attribute with JsonFormat, JsonbDateFormat and #Schema, with same results.
Also tried adding Jackson Provider (ContextResolver), which works for the server-side, but no changes on the client-side.
Code snippet of testes annotations:
import com.fasterxml.jackson.annotation.JsonFormat;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import javax.json.bind.annotation.JsonbDateFormat;
#JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM")
#JsonbDateFormat(value = "yyyy-MM")
// Next one I'm guessing. Can't find docs for this.
#Schema(type = SchemaType.STRING, implementation = YearMonth.class, pattern = "yyyy-MM")
private YearMonth referencia;
Environment:
Wildfly 21
Java SE 11
microprofile-rest-client-api:2.0
microprofile-openapi-api:2.0
1. First, you need to enable Jackson, as RESTEasy defaults to JSONB. For this you need to add this system property:
resteasy.preferJacksonOverJsonB = true
Add system property as your preference, using -Dproperty=value command line syntax or whatever. In our case, we use WildFly configuration (e.g. standalone.xml):
<system-properties>
<property name="resteasy.preferJacksonOverJsonB" value="true"/>
</system-properties>
2. Then you can add Jackson configuration provider to your REST client interface:
import org.eclipse.microprofile.rest.client.annotation.RegisterProvider;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
#RegisterProvider(JacksonConfiguration.class)
#RegisterRestClient
public interface RestTestService {
// methods...
}
Now, Java 8 Date Time API will correctly be serialized, and you can add custom formats with #JsonFormat, if needed.
Plus: Here a sample of a Jackson configuration provider that can be used on client and server-side too:
import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
#Provider
public class JacksonConfiguration implements ContextResolver<ObjectMapper> {
private final ObjectMapper mapper;
public JacksonConfiguration() {
mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
#Override
public ObjectMapper getContext(Class<?> type) {
return mapper;
}
}
I'm switching to jackson json because it's apparently faster than minimal-json. I am however confused to how it works as the documentation is confusing.
Is it:
import com.fasterxml.jackson...
or:
import org.codehaus.jackson...
I have tried both, I have the file jackson-core-2.5.0.jar and the import com.fasterxml.jackson works, however I am not able to do the following:
ObjectMapper mapper = new ObjectMapper();
Jackson 1 was part of org.codehaus. Jackson 2 is now part of com.fasterxml and is in no way backwards compatible.
The ObjectMapper type is in the package com.fasterxml.jackson.databind.
The Situation
I have an enum class called Errors and it is in a common project. The errors enum contains an int code and a String text. The Errors enum is used in two different projects. One project is a Spring based project and the other project is in a non-Spring J2EE application.
In the Spring based project, Jackson is the library used for converting the Errors enum to Json. So if there is a request we can return an Errors enum object and it will be automatically converted to the json representation, which is {code: int, text: error} The Errors enum has the annotation:
#JsonSerialize(using=ErrorsSerializer.class)
The ErrorsSerializer class is located in the Spring based application.
In the common project, where the Errors enum is located, Gson is the library used for converting objects to its Json representation and we want to remove any references to the Jackson library.
The problem
If i remove the annotation from the Errors enum the Spring project will not return the correct representation of the Errors enum, it will only return the constant variable in quotes.
The Question
How do i remove the annotation of the Errors enum (which will remove any Jackson dependencies in the common project) and yet still have the Spring project return the correct Json representation?
Best Option So Far
The best option i have come up with so far is to create an Errors container object in the Spring application that contains the Errors enum and also has the json serialize annotation.
Thanks!
You can also specify serializer in Spring based project using Module functionality. Module allow users to customize ObjectMapper object without annotations. See below example:
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
public class JacksonProgram {
public static void main(String[] args) throws Exception {
SimpleModule module = new SimpleModule();
module.addSerializer(Error.class, new ErrorJsonSerializer());
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
System.out.println(mapper.writeValueAsString(Error.NOT_FOUND));
}
}
Above example prints:
{"code":1,"text":"Not found"}
See below links to find solution how to configure ObjectMapper in Spring app:
Register a custom Jackson ObjectMapper using Spring Javaconfig.
Configurating ObjectMapper in Spring.