Is there a way to use Jackson's SerializationFeature with annotations - json

I'm trying to use SerializationConfig.Feature.WRITE_CHAR_ARRAYS_AS_JSON_ARRAYS but I'm not configuring the mapper myself, relying on annotations exclusively and letting Spring's RestTemplate (de)serialize automatically. Is there a way to enable the aforementioned feature in this scenario (i.e. annotations only)?
NOTE: I'm using Jackson 1.x and can't upgrade due to other libs...

With JAX-RS (like DropWizard) you can actually annotated resource endpoints, using #JacksonFeatures
public class Resource {
#Path("item")
#GET
#JacksonFeatures(serializationEnable={ SerializationFeature.WRAP_ROOT_VALUE })
public Pojo getItem(String id) {
...
}
}
I don't know if Spring exposes similar functionality, but it seems possible it does. And if not, it is something they should be able to add to allow per-endpoint setting/clearing of SerializationFeatures / DeserializationFeatures. So if it is not available, maybe file a feature request for Spring project?

Yes, it is possible.
checkout this link: http://jackson.codehaus.org/1.7.0/javadoc/org/codehaus/jackson/map/annotate/JsonSerialize.html
Example:
#JsonSerialize(using=MySerializer.class,
as=MySubClass.class,
include=JsonSerialize.Inclusion.NON_NULL,
typing=JsonSerialize.Typing.STATIC
)

Related

How to use Hystrix with Spring WebFlux WebClients?

I'm using Spring WebFlux with functional endpoints to create an API. To provide the results I want, I need to consume an external RESTful API, and to do that in a async way I'm using a WebClient implementation. It works well and goes like this:
public WeatherWebClient() {
this.weatherWebClient = WebClient.create("http://api.openweathermap.org/data/2.5/weather");
}
public Mono<WeatherApiResponse> getWeatherByCityName(String cityName) {
return weatherWebClient
.get()
.uri(uriBuilder -> uriBuilder
.queryParam("q", cityName)
.queryParam("units", "metric")
.queryParam("appid", API_KEY)
.build())
.accept(APPLICATION_JSON)
.retrieve()
.bodyToMono(WeatherApiResponse.class);
}
As this performs network access, it's a good use case for NetFlix OSS Hystrix. I've tried using spring-cloud-starter-netflix-hystrix, adding #HystrixCommand to the method above, but there's no way to make it trip the circuit, even if I set a bad URL (404) or wrong API_KEY (401).
I thought this could be a problem of compatibility with the WebFlux itself, but setting property #HystrixProperty(name="circuitBreaker.forceOpen", value="true") indeed forces the fallback method to run.
Am I missing something? Is this approach incompatible with Spring WebClients?
Thanks!
#HystrixCommand won't really work, because Hystrix doesn't threat Mono/Flux any different from Java primitives.
Hystrix doesn't monitor content of Mono, but only the result of call public Mono<WeatherApiResponse> getWeatherByCityName(String cityName).
This result is always OK, because reactive-call-chain creation will always succeed.
What you need, is to make Hystrix threat Mono/Flux differently.
In Spring Cloud, there is a builder, to wrap Mono/Flux with HystrixCommand.
Mono<WeatherApiResponse> call = this.getWeatherByCityName(String cityName);
Mono<WeatherApiResponse> callWrappedWithHystrix = HystrixCommands
.from(call)
.fallback(Mono.just(WeatherApiResponse.EMPTY))
.commandName("getWeatherByCityName")
.toMono();

Seam 2.3 RESTEasy on JBoss 7.1 #JsonIgnore

How to achieve that some properties are ignored in the JSON-output (like XmlTransient for XML-output)?
#GET
#Path("/{companyId}")
#Produces(MediaType.APPLICATION_JSON)
public PortfolioCompany getCompany(#PathParam("companyId") long id);
I've been playing around with the RESTeasy-support in Seam 2.3 deployed as an EAR on a JBoss 7.1. I started by adding the same dependencies to my ejb-project as in the Seam-restbay-example.
It is basically working fine for #Produces(MediaType.APPLICATION_XML), where all properties annotated with #XmlTransient are ignored, in order to prevent some LazyInitialisationExceptions.
But how to achieve this behavior for #Produces(MediaType.APPLICATION_JSON)?
I've read Seam uses Jettison by default, which uses the #XmlTransient annotation for both, XML and JSON (because technically it transforms from XML -> to JSON). But I get a "Caused by: org.codehaus.jackson.map.JsonMappingException: No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer" which indicates that in fact it is using Jackson..?
For Jackson there is the annotation like #JsonIgnore, but having the same maven dependencies like restbay - this "cannot to be resolved to a type".
/**
* #return the contact
*/
#OneToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY)
#XmlTransient // working for produces XML but not for JSON
//#JsonIgnore = unknown type
public Contact getContact() {
return contact;
}
Anyone any experiences or hints on that?
thanks
EDIT: Really no one having the need of realizing lazy collections for REST-services with Seam??
After some research:
#JsonIdentityInfo(generator = ObjectIdGenerators.IntSequenceGenerator.class, property ="#id")
is what apparently would be needed. But that is only provided with Jackson 2.x. But the seam2.3/jboss7 setup is obviously using Jackson 1.9...
The default annotation mode of #XmlType/#XmlRootElement is to capture everyfield, including the lazy initializer from hibernate. Use #XmlAccessorType(XmlAccessType.NONE) in your entities and then individually annotate the fiels with #XmlElement so that only the necessary fields are processeded

Globally configure Jackson properties using Spring?

i am using Jackson and was wondering if it is possible to set global properties using resources.xml?
Example:
In some places i need to do:
jsonMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
It would be nice that i can configure Jackson to do this global using spring resources.xml,
any suggestion on how to do this?
You can do this easily, just extend the org.codehaus.jackson.map.ObjectMapper class and specify all your properties in the constructor(or you can accept a map as well): Then autowire your own ObjectMapper where you need it.
Not out of the box -- but maybe someone could build such an extension, release as Jackson module?

REST with Spring and Jackson full data binding

I'm using Spring MVC to handle JSON POST requests. Underneath the covers I'm using the MappingJacksonHttpMessageConverter built on the Jackson JSON processor and enabled when you use the mvc:annotation-driven.
One of my services receives a list of actions:
#RequestMapping(value="/executeActions", method=RequestMethod.POST)
public #ResponseBody String executeActions(#RequestBody List<ActionImpl> actions) {
logger.info("executeActions");
return "ACK";
}
I have found that Jackson maps the requestBody to a List of java.util.LinkedHashMap items (simple data binding). Instead, I would like the request to be bound to a List of typed objects (in this case "ActionImpl").
I know this is easy to do if you use Jackson's ObjectMapper directly:
List<ActionImpl> result = mapper.readValue(src, new TypeReference<List<ActionImpl>>() { });
but I was wondering what's the best way to achieve this when using Spring MVC and MappingJacksonHttpMessageConverter. Any hints?
Thanks
I have found that you can also work around the type erasure issue by using an array as the #RequestBody instead of a collection. For example, the following would work:
public #ResponseBody String executeActions(#RequestBody ActionImpl[] actions) { //... }
I suspect problem is due to type erasure, i.e. instead of passing generic parameter type, maybe only actions.getClass() is passed; and this would give type equivalent of List< ?>.
If this is true, one possibility would be to use an intermediate sub-class, like:
public class ActionImplList extends ArrayList<ActionImpl> { }
because this will the retain type information even if only class is passed.
So then:
public #ResponseBody String executeActions(#RequestBody ActionImplList actions)
would do the trick. Not optimal but should work.
I hope someone with more Spring MVC knowledge can shed light on why parameter type is not being passed (perhaps it's a bug?), but at least there is a work around.
For your information, the feature will be available in Spring 3.2 (see https://jira.springsource.org/browse/SPR-9570)
I just tested it on current M2 and it works like a charm out of the box (no need to provide additionnal annotation to provide the parameterized type, it will be automatically resolved by new MessageConverter)
This question is already old, but I think I can contribute a bit anyway.
Like StaxMan pointed out, this is due to type erasure. It definitely should be possible, because you can get the generic arguments via reflection from the method definition. However, the problem is the API of the HttpMessageConverter:
T read(Class<? extends T> clazz, HttpInputMessage inputMessage);
Here, only List.class will be passed to the method. So, as you can see, it is impossible to implement a HttpMessageConverter that calculates the real type by looking at the method parameter type, as that is not available.
Nevertheless, it is possible to code your own workaround - you just won't be using HttpMessageConverter. Spring MVC allows you to write your own WebArgumentResolver that kicks in before the standard resolution methods. You can for example use your own custom annotation (#JsonRequestBody?) that directly uses an ObjectMapper to parse your value. You will be able to provide the parameter type from the method:
final Type parameterType= method.getParameterTypes()[index];
List<ActionImpl> result = mapper.readValue(src, new TypeReference<Object>>() {
#Override
public Type getType() {
return parameterType;
}
});
Not really the way TypeReference was intended to be used I presume, but ObjectMapper doesn't provide a more suitable method.
Have you tried declaring the method as:
executeActions(#RequestBody TypeReference<List<ActionImpl>> actions)
I haven't tried it, but based on your question it's the first thing I would try.

Castle Windsor Typed Factory Facility equivalents

do any other .NET IoC containers provide equivalent functionality to the typed factory facility in Castle Windsor?
e.g. if I am using an abstract factory pattern in a WPF application:
public class MyViewModel
{
private IAnotherViewModelFactory factory;
public void ShowAnotherViewModel()
{
viewController.ShowView(factory.GetAnotherViewModel());
}
}
I don't want to have to create a manual implementation of IAnotherViewModelFactory for every type of ViewModel I wish to show, I want the container to take care of this for me.
AutoFac has a feature called Delegate Factories, but as far as I can tell, it works only with delegates, and not interfaces.
I haven't encountered anything similar to Castle's Typed Factory Facility in neither StructureMap nor Unity, but that doesn't necessarily mean that they're not there...
The only way I can imagine that something like this could be implemented for interfaces is via a dynamic proxy. Since Castle Windsor has a Dynamic Proxy, but few other containers have anything similar, this might go a long way to explain why this feature isn't ubiquitous.
Unity also offers interception capabilities, so it must have some sort of dynamic proxy implementation, but I'm pretty sure it doesn't have anything equivalent to Typed Factories. Compared to other containers, Unity is rather basic.
In Autofac you can implement typed factories on top of the delegate approach Mark mentions. E.g.
class AnotherViewModelFactory : IAnotherViewModelFactory {
Func<AnotherViewModel> _factory;
public AnotherViewModelFactory(Func<AnotherViewModel> factory) {
_factory = factory;
}
public AnotherViewModel GetAnotherViewModel() {
return _factory();
}
}
If this class is registered with the container, along with AnotherViewModel Autofac will provide the Func<AnotherViewModel> implementation implicitly:
builder.RegisterType<AnotherViewModel>();
builder.RegisterType<AnotherViewModelFactory>()
.As<IAnotherViewModelFactory>();
Practically any interface you can implement using Typed Factory Facility can be implemented in Autofac using this kind of approach. The primary difference is that the Windsor implementation configures the factory through the component registration API, while in Autofac the factory is a component in its own right.
For more sophisticated examples you might like to look at: http://code.google.com/p/autofac/wiki/RelationshipTypes and http://nblumhardt.com/2010/01/the-relationship-zoo/.
I have recently implemented an equivalent of Castle Windsor Typed Factories for Unity. You can find the project at https://github.com/PombeirP/Unity.TypedFactories, and the NuGet package at http://nuget.org/packages/Unity.TypedFactories.
The usage is the following:
unityContainer
.RegisterTypedFactory<IFooFactory>()
.ForConcreteType<Foo>();
The parameter matching is done by name, which is fine for my needs, although the library could easily be extended to support other needs.