We are migrating our project from jersey 1.X version to 2.X .
public static Filter buildFilter(String s) throws Exception {
JSONJAXBContext context = new JSONJAXBContext(JSONConfiguration.natural().build(),FilterModel.class);
JSONUnmarshaller unmarshaller = context.createJSONUnmarshaller();
FilterModel model = unmarshaller.unmarshalFromJSON(new StringReader(s),
FilterModel.class);
return model.build();
}
So my question is how we can do the changes and compatible the above code to Jersey 2.X ?
Thanks advance.
Related
We are working on the migration from resteasy 2.x to 3.x and are not happy about the use of the deprecated org.jboss.resteasy.client.ClientResponse within org.jboss.resteasy.client.core.ClientErrorInterceptor#handle - method.
Thus we are searching for proper replacement with which we are able to rethrow all service exception at a single place within the service client library, even if ClientResponse is replaced in new versions of resteasy.
The existing solution with resteasy 2.x looks like:
public class ServiceClientErrorInterceptor implements ClientErrorInterceptor
{
#Override
public void handle(ClientResponse<?> response)
{
throw response.getEntity(ServiceExceptionObject.class).getException();
}
}
I created a Spring boot application that sends messages to Kafka queues (using spring integrations kafka support). I want to send arbitrary json-serialized objects.
Is there a way to get/inject a json-de-/serializer within my spring boot application?
Or how to ad hoc de-/ serialize an object?
what are good practices to apply serialization?
Apache Kafka stores and transports Byte arrays in its topics. It ships with a number of built in (de)serializers but a JSON one is not included. Luckily, the Spring Kafka framework includes a support package that contains a JSON (de)serializer that uses a Jackson ObjectMapper under the covers.
You can add a config file like this
#Configuration
public class KafkaConfiguration {
#Bean
public ConsumerFactory<String, Operation> consumerFactory(KafkaProperties kafkaProperties) {
return new DefaultKafkaConsumerFactory<>(kafkaProperties.buildConsumerProperties(), new StringDeserializer(), new JsonDeserializer<>(Operation.class));
}
#Bean
public ConcurrentKafkaListenerContainerFactory<String, Operation> kafkaListenerContainerFactory(ConsumerFactory<String, Operation> consumerFactory) {
ConcurrentKafkaListenerContainerFactory<String, Operation> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory);
return factory;
}
}
Replace Operation with your class which you want to deserialize.
I have a dependency to the third-party library Woorea Openstack-SDK (https://github.com/woorea/openstack-java-sdk) which uses Jackson 1.x annotations. Because of the Jackson update (Jackson 1.x -> Jackson 2.x) in Jersey 2.9, the Openstack-SDK becomes incompatible.
Is there a way to use Jersey 2.9 together with Jackson 1.x as JSON provider?
I used https://github.com/FasterXML/jackson-jaxrs-providers/ to provide Jackson 2.x to previous versions of Jersey (wihtout Jackson 2.x support). Should be an alternative to provide now Jackson 1.x to new versions of Jersey(with Jackson 2.0 support). Otherwise, check the implementation in the above link. You could do the same, since it's mostly about registering a new provider.
I found a solution... I removed the dependency to the artifact jersey-media-json-jackson and registered the following feature:
package test;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.MessageBodyReader;
import javax.ws.rs.ext.MessageBodyWriter;
import org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider;
import org.codehaus.jackson.jaxrs.JsonMappingExceptionMapper;
import org.codehaus.jackson.jaxrs.JsonParseExceptionMapper;
import org.glassfish.jersey.CommonProperties;
import org.glassfish.jersey.internal.InternalProperties;
import org.glassfish.jersey.internal.util.PropertiesHelper;
public class Jackson1xFeature implements Feature {
private final static String JSON_FEATURE = Jackson1xFeature.class.getSimpleName();
#Override
public boolean configure(final FeatureContext context) {
final Configuration config = context.getConfiguration();
final String jsonFeature = CommonProperties.getValue(config.getProperties(), config.getRuntimeType(), InternalProperties.JSON_FEATURE, JSON_FEATURE, String.class);
// Other JSON providers registered.
if (!JSON_FEATURE.equalsIgnoreCase(jsonFeature)) {
return false;
}
// Disable other JSON providers.
context.property(PropertiesHelper.getPropertyNameForRuntime(InternalProperties.JSON_FEATURE, config.getRuntimeType()), JSON_FEATURE);
// Register Jackson.
if (!config.isRegistered(JacksonJaxbJsonProvider.class)) {
// add the default Jackson exception mappers
context.register(JsonParseExceptionMapper.class);
context.register(JsonMappingExceptionMapper.class);
context.register(JacksonJaxbJsonProvider.class, MessageBodyReader.class, MessageBodyWriter.class);
}
return true;
}
}
I have a jersey webservice running 1.17 and supports returning responses via both XML and JSON via the #Produces annotation. I am assuming it uses JAXB by default when returning JSON responses but I have no way to confirm it. As of now, my existing clients also use the same JAXB serializer/deserializer. I want to create a new client that uses Jackson without impacting the existing clients.
The JAXB JSON response is incompatible for Jackson for Maps. the JSON for a map using JAXB is of the form
"mapName":{"entry":[{"key":"key1","value":"value1"},{"key":"key2","value":"value2"}]}
and Jackson fails to parse this. Is there any way to make jackson parse this JSON?
Another Attempt: Switching Jersey to use Jackson
This isn't the preferred option but I tried setting "com.sun.jersey.api.json.POJOMappingFeature" to true to allow it to use Jackson for JSON Serialization/Deserialization however the service ends up returning 500s on response without logging any exceptions. the log4j logger level is set to TRACE. I enabled the ContainerRepsonseFilter to confirm 500s in the response and to my surprise, it logs the successful 2xx response. My guess is the problem occurs somewhere further down the stack but I don't know where.
I ended up with using MOXy which is able to parse the above json format.
#Provider
public class JsonMoxyConfigurationContextResolver implements ContextResolver {
private final MoxyJsonConfig config;
public JsonMoxyConfigurationContextResolver() {
final Map<String, String> namespacePrefixMapper = new HashMap<String, String>();
namespacePrefixMapper.put("http://www.w3.org/2001/XMLSchema-instance", "xsi");
config = new MoxyJsonConfig()
.setNamespacePrefixMapper(namespacePrefixMapper)
.setNamespaceSeparator(':');
}
#Override
public MoxyJsonConfig getContext(Class<?> objectType) {
return config;
}
}
and enabled it Jersey 2.x client using
cc.register(JsonMoxyConfigurationContextResolver.class);
I'm new to both Jackson and Spring, so please excuse me if this is a dumb question. I've been working on a simple spring project which handles JSON requests. I have GET and DELETE working, but I'm getting an error when I try to POST:
SEVERE: Servlet.service() for servlet [mvc-dispatcher] in context with path [/CynergyRestStarterKit] threw exception [Handler processing failed; ...with root cause
java.lang.NoSuchMethodError: org.codehaus.jackson.map.type.TypeFactory.type(Ljava/lang/reflect/Type;Lorg/codehaus/jackson/type/JavaType;)Lorg/codehaus/jackson/type/JavaType;
at org.springframework.http.converter.json.MappingJacksonHttpMessageConverter.getJavaType(MappingJacksonHttpMessageConverter.java:229)
Here is my Java service:
#RequestMapping(value = "/todos", method = RequestMethod.GET)
public #ResponseBody
List<TodoItem> getTodos() {
return tasks;
}
#RequestMapping(value = "/todo/create", method = RequestMethod.POST)
public #ResponseBody
TodoItem createTodo(#RequestBody TodoItem item) {
return null;
}
What am I doing wrong?
What version of Spring and Jackson are you using?
This seems to indicate a version issue.
I see that you are using 1.x of Jackson (codehaus vs fasterxml). I would upgrade both Spring and Jackson to the latest version.
I had the same problem using spring-webmvc 3.2.9, after several retires i found that my project needed the following libraries:
jackson-annotations-2.3.3
jackson-core-2.3.3
jackson-mapper-asl-1.9.13
jackson-core-asl-19.3
So adding these solved the problem