jersey + json parsing - json

I have the following controller:
#POST
#Path("endpoint")
#Consumes({MediaType.APPLICATION_JSON+ ";charset=utf-8"})
#Produces({MediaType.APPLICATION_JSON + ";charset=utf-8", "application/javascript;charset=utf-8"})
public void postData(#Context HttpHeaders httpHeaders,
#Context HttpServletRequest request, #Context UriInfo uriInfo,
JSONData postedData) {
}
My related pom dependencies are:
<dependency>
<groupId>org.glassfish.jersey.containers</groupId>
<artifactId>jersey-container-servlet</artifactId>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.core</groupId>
<artifactId>jersey-server</artifactId>
<exclusions>
<exclusion>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-jaxb</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>runtime</scope>
</dependency>
The version resolved in the dependencies is 2.17 for all the dependencies.
I am registering the JacksonFeature class in the properties
jersey.config.server.provider.classnames=org.glassfish.jersey.jackson.JacksonFeature
And I get the following exception when performing a request: (the JSONData class is very simple by now, only a String property annotated with lombok to generate getter and setters)
2020-12-07 12:31:56,910 ERROR [jersey-server-managed-async-executor-0]
JsonExceptionMapper - at
es.colbenson.sb.ws.JsonExceptionMapper.toResponse(JsonExceptionMapper.java:28)
Exception: java.lang.NoSuchMethodError java.lang.NoSuchMethodError:
com.fasterxml.jackson.databind.util.BeanUtil.okNameForSetter(Lcom/fasterxml/jackson/databind/introspect/AnnotatedMethod;)Ljava/lang/String;
at
com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector.findNameForDeserialization(JaxbAnnotationIntrospector.java:875)
~[jackson-module-jaxb-annotations-2.3.2.jar:2.3.2]
I've also tried registering the JacksonFeature class on my application constructor:
register(JacksonFeature)
But I can get this working. Any thoughts?
Also I can see this in the exception Stack Trace, which seems to be pointing to a jackson-databind-2.9.8 inside, but I'm not sure if it is a kind of conflict...
at
com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addSetterMethod(POJOPropertiesCollector.java:620)
~[jackson-databind-2.9.8.jar:2.9.8] at
com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addMethods(POJOPropertiesCollector.java:535)
~[jackson-databind-2.9.8.jar:2.9.8] at
com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:309)
~[jackson-databind-2.9.8.jar:2.9.8] at
com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getPropertyMap(POJOPropertiesCollector.java:287)
~[jackson-databind-2.9.8.jar:2.9.8] at
com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getProperties(POJOPropertiesCollector.java:170)
~[jackson-databind-2.9.8.jar:2.9.8]

I had to remove this dependency:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-json-jackson</artifactId>
<scope>runtime</scope>
</dependency>
And add this other
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>2.9.8</version>
</dependency>
Then register this provider:
jersey.config.server.provider.classnames=com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider
It seems a matter of using the proper jackson binder for this version of jersey

Related

Camel json validator support for json draft 07

We are using Apache Camel Java DSL and the json-validator component to validate json requests against a json schema. The current camel version is 2.22.0, according to the camel documentation this supports JSON schema v4, v6, v7 and v2019-09 using the NetworkNT JSON Schema library. However, when I try a JSON schema draft 07, I get an error when running tests "Caused by: com.networknt.schema.JsonSchemaException: Unknown Metaschema: http://json-schema.org/draft-07/schema#".
When i revert back to json schema draft 04 it works fine.
Any ideas on how to get this working?
The default draft is the 4th one, but you can override the schema validator (JsonSchemaLoader), by defining a bean.
#Bean(name = "mySchemaLoader")
public JsonSchemaLoader mySchemaLoader() {
return (camelContext, schemaStream) -> JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7)
.getSchema(schemaStream);
}
with that we just create a bean wich will return a V7 schema validator, if you want to override the default configuration
...
ObjectMapper mapper = new ObjectMapper();
JsonSchemaFactory validatorFactory = JsonSchemaFactory.builder(JsonSchemaFactory.getInstance(SpecVersion.VersionFlag.V7)).objectMapper(mapper).build();
....
So having the bean, you just have to said to camel that you are going to usea that bean via query param
public void configureRemote() throws Exception {
from("direct:getPrescripciones")
.recipientList(
simple"${header.url}?bridgeEndpoint=true"))
.to("json-validator:deliveryReport.schema.json?schemaLoader=#bean:mySchemaLoader")
.end();
}
that's all
here the dependencies I used
<properties>
<java.version>1.8</java.version>
<camel.version>3.4.0</camel.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-json-validator-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jackson</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-http</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-jolt</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-servlet-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-swagger-java-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel.springboot</groupId>
<artifactId>camel-google-pubsub-starter</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.apache.camel</groupId>
<artifactId>camel-google-pubsub</artifactId>
<version>${camel.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>
The camel version supporting the v7 is 3.4.0
The documentation you're looking for is on 2.x and in that case it's correctly noted that only v4 is supported: https://camel.apache.org/components/2.x/json-validator-component.html

NoClassDefFound error while Running with PowerMock

I am getting this error:
java.lang.NoClassDefFoundError: org/powermock/reflect/proxyframework/ClassLoaderRegisterProxyFramework
at org.powermock.tests.utils.impl.AbstractCommonTestSuiteChunkerImpl.registerProxyframework(AbstractCommonTestSuiteChunkerImpl.java:101)
at org.powermock.tests.utils.impl.AbstractCommonTestSuiteChunkerImpl.chunkClass(AbstractCommonTestSuiteChunkerImpl.java:114)
at org.powermock.tests.utils.impl.AbstractCommonTestSuiteChunkerImpl.<init>(AbstractCommonTestSuiteChunkerImpl.java:60)
at org.powermock.tests.utils.impl.AbstractCommonTestSuiteChunkerImpl.<init>(AbstractCommonTestSuiteChunkerImpl.java:54)
at org.powermock.tests.utils.impl.AbstractTestSuiteChunkerImpl.<init>(AbstractTestSuiteChunkerImpl.java:58)
at org.powermock.modules.junit4.common.internal.impl.JUnit4TestSuiteChunkerImpl.<init>(JUnit4TestSuiteChunkerImpl.java:49)
at org.powermock.modules.junit4.common.internal.impl.AbstractCommonPowerMockRunner.<init>(AbstractCommonPowerMockRunner.java:32)
at org.powermock.modules.junit4.PowerMockRunner.<init>(PowerMockRunner.java:34)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
at org.junit.internal.builders.AnnotatedBuilder.buildRunner(AnnotatedBuilder.java:104)
at org.junit.internal.builders.AnnotatedBuilder.runnerForClass(AnnotatedBuilder.java:86)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:26)
at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:59)
at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:33)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createUnfilteredTest(JUnit4TestLoader.java:84)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:70)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:43)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:444)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.ClassNotFoundException: org.powermock.reflect.proxyframework.ClassLoaderRegisterProxyFramework
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 25 more
I've added these dependencies in my pom.xml. I've already checked the stackflow for similar implementations and did a clean install. My project is building file but running tests is giving error. I am trying to run through eclipse.
<!-- Power Mock dependencies -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4-legacy</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-reflect</artifactId>
<version>1.7.0</version>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-easymock</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.easymock</groupId>
<artifactId>easymock</artifactId>
<version>3.4</version>
<scope>test</scope>
</dependency>
I am running java class with PowerMockRunner and injecting my test class using annotation InjectMock. Then mocking static class using MockStatic method. Also, i've added PrepareForTest annotation and added Class which has static methods in that location.
I updated my code and followed few examples, but this error is coming. What am i am doing wrong?
My code is like this.
class A{
void static method testA(String str){ .... do something; }
}
class B{
testB(String s)
{ A.testA(s);
}
}
Now when i try to run test case on my class A using PowerMockRunner. I've given annotations on testcase #preparefortest({A.class}) #runwith(PowerMockRunner.class)
I saw the same error when using PowerMock 1.7.1. In the absence of an explicit dependency, maven was pulling in version 1.6.5 of powermock-core. Adding an explicit dependency on version 1.7.1 of powermock-core fixed this error for me.
So your solution should be to add an explicit dependency on version 1.7.0 of powermock-core:
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-core</artifactId>
<version>1.7.0</version>
<scope>test</scope>
</dependency>

Reasteasy desn't found the jettison jaxb rpovider

I am getting:
org.jboss.resteasy.plugins.providers.jaxb.JAXBMarshalException: Could not find JAXBContextFinder for media type: application/json
at org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBProvider.findJAXBContext(AbstractJAXBProvider.java:50)
at org.jboss.resteasy.plugins.providers.jaxb.AbstractJAXBProvider.getMarshaller(AbstractJAXBProvider.java:127)
on the client side... i have the following pom.xml where you can see jettison jaxb provider is on as well as the jettison core jar:
<repositories>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/maven2</url>
</repository>
<repository>
<id>maven</id>
<url>http://mvnrepository.com//maven2</url>
</repository>
</repositories>
<dependencies>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>5.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.primefaces</groupId>
<artifactId>primefaces</artifactId>
<version>5.1</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.2.Final</version>
</dependency>
<!-- JAXB support -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>3.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>jaxrs-api</artifactId>
<version>3.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.2.Final</version>
</dependency>
<dependency>
<groupId>net.sf.scannotation</groupId>
<artifactId>scannotation</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jettison-provider</artifactId>
<version>3.0.10.Final</version>
</dependency>
<dependency>
<groupId>org.codehaus.jettison</groupId>
<artifactId>jettison</artifactId>
<version>1.3.7</version>
</dependency>
</dependencies>
In the User DTO used on my client call i have the XmlRootElement annotation and the call is:
public UserDTO getUserData(String userName) {
webTarget = client.target(BASE_URI).path("Login/GetUserData");
Form form = new Form();
form.param("userName", userName);
Response requestResult;
Entity<Form> entity;
MediaType sent = MediaType.APPLICATION_FORM_URLENCODED_TYPE;
entity = Entity.entity(form, sent);
MediaType [] accepted = {MediaType.APPLICATION_JSON_TYPE};
requestResult = webTarget.request(accepted)
.post(entity);
UserDTO result = (UserDTO)requestResult.getEntity();
return result;
}
any idea?
According to resteasy 3.0.2 jettison example you don't need resteasy-jaxb-provider dependency. I think that's included in resteasy-jettison-provider.
See if removing resteasy-jaxb-provider dependency, and updating resteasy-jettison-provider version to 3.0.2 helps..

posting JSON to Spring rest controller

I got stuck on sending POST to my rest controller. When I try to update my entry, I get 415 status. I have this error in my web application, written in angular JS and chrome tool for rest API.
Controller code:
#RequestMapping(value = "/update", method = RequestMethod.POST)
public void updateEntry(#RequestBody Entry entry) {
System.out.println("editing: " + entry.toString());
}
My pom.xml:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.1.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.1.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.2.RELEASE</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--JSON-->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
I'm trying to send something like this:
{"id":"5471db49b0ca59357d6beded","name":"EADS 3 Sigma Nearchos"}
My entry contains only two fields: String id, String name.
Spring Framework raised library requirements, including Jackson. You should update to Jackson 2.1+ when using Spring 4.1.x.
Check out the migration page on github for more details.

RestEasy Jettison/Jackson customization

I'm trying to use my objects with JAXB annotations for application/json output with my JAX-RS resource. I'm running on JBoss AS7 with RestEasy (both lastest versions - 7.1.1.Final and 2.3.4.Final). The issue is that I would like to customize my JSON output. I must note that I don't care if I will use Jettison or Jackson, but I was able only make Jettison work (deploy application) without errors. I also would like to stick only with JAXB annotations on my objects if possible - but it is not necessairly needed.
1) I want to omit "#" within XmlAttribute annotated fields. I found out property how to do it with Jettison, but I don't know how to configure it on JBoss AS7. Didn't find any ContextResolver example.
2) I would like to have "normal" JSON arrays, e.g.
#XmlRootElement(name = "root")
#XmlAccessorType(XmlAccessType.FIELD)
public class Root {
#XmlElementRef(type = Entry.class, required = false)
// no difference with #XmlElement
private Set<Entry> entries;
}
serializes into
{"entries":
{"entry":[{...},{...},{...}]}
}
and I would expect
{"entries":
[
{"entry":{...}},
{"entry":{...}},
{"entry":{...}}
]
}
or just (omit XmlRootElement)
{"entries":
[{...},{...},{...}]
}
3) As I noted, I don't care what provider (Jettison/Jackson) will I use but it is hard to find working example how to correctly set maven dependencies for application to be deployable without errors. So far I'm using:
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>${resteasyVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>${resteasyVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jettison-provider</artifactId>
<version>${resteasyVersion}</version>
<!--<scope>provided</scope>-->
<exclusions>
<exclusion>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</exclusion>
<exclusion>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
</exclusion>
<exclusion>
<groupId>javax.xml.stream</groupId>
<artifactId>stax-api</artifactId>
</exclusion>
</exclusions>
</dependency>
Thanks for all answers
So far I managed to make Jackson working and use its provider-specific annotations (#JsonProperty ... and so) which solved my problem. I tried to find only JAXB solution but I can accept also this.
Btw my dependencies
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>${resteasyVersion}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>${resteasyVersion}</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>${resteasyVersion}</version>
</dependency>