#RequestBody can not read MultiMap - java

I am trying to use MultiValueMap (implementation of MultiMap) from apache collections. I am using Spring MVC's #RequestBody annotation. However, I keep getting HTTPMediaTypeNotSupportedException. When I change the implementation to use Map of Map from Java Util, it works fine.
Any clue? Is Jackson API unable to work with anything other than core JDK Types?

A #RequestBody parameter is converted using HttpMessageConverter. For MultiValueMap you should register a custom converter. For more details, check this and this.

Related

Map partial json to dto

I was working with rest api and I have a json on POST which I need to map to a dto. But, I have only 5 properties on json , but more than that on the dto. How do I use bean mapper to map it automatically and what about the rest of the properties. Will they be set to Null?
Spring boot comes with Jackson deserializer out-of-the-box. So, it will use the proper method (default null value or constructor properties, based on your settings). For fine tuner, see more at JsonInclude annotation for collections include's strategy and so.
JsonInclude

Auto detection Jackson for Spring

I am working on a project that uses Spring framework and Jackson. However, I was not able to find a place, where it is being plugged. I looked at many examples on the web and most of them use bean of class org.springframework.http.converter.json.MappingJacksonHttpMessageConverter to allow deserialization of #ResponseBody.
So, I was not able to find any references to MappingJacksonHttpMessageConverter.
My question: Will spring framework automatically use Jackson if it will find it on its classpath to convert JSON into #ResponseBody object?
What are other ways how Jackson can be enabled?
If you wire up your spring project using #EnableWebMvc or via XML by using the tag <mvc:annotation-driven /> you enable a bunch of features. You can read the detailed list of features in the original Spring docs.
One of the features that are enabled is the support for #RequestBody method parameters and #ResponseBody method return values. This is done via the HttpMessageConverter component and the feature is enabled for methods that are annotated with #RequestMapping or #ExceptionHandler.
The following lists the converters that are registered by default:
ByteArrayHttpMessageConverter converts byte arrays.
StringHttpMessageConverter converts strings.
ResourceHttpMessageConverter converts to/from org.springframework.core.io.Resource for all media types.
SourceHttpMessageConverter converts to/from a javax.xml.transform.Source.
FormHttpMessageConverter converts form data to/from a MultiValueMap.
Jaxb2RootElementHttpMessageConverter converts Java objects to/from XML — added if JAXB2 is present on the classpath.
MappingJackson2HttpMessageConverter (or MappingJacksonHttpMessageConverter) converts to/from JSON — added if Jackson 2 (or Jackson) is present on the classpath.
AtomFeedHttpMessageConverter converts Atom feeds — added if Rome is present on the classpath.
RssChannelHttpMessageConverter converts RSS feeds — added if Rome is present on the classpath.
So, if you have a web enabled project with Jackson available on the classpath, Spring will automatically convert return values from a controller-method that is annotated with #ResponseBody (if the client caller accepts JSON that is which means that the accept header typically must be set to application/json).
If you wish to override the HttpMessageConverters you can implement the following:
#Configuration
#EnableWebMvc
public class YourConfiguration extends WebMvcConfigurerAdapter {
#Override
public void configureMessageConverters(
List<HttpMessageConverter<?>> converters) {
// Do your magic, override your stuff
}
}
For a good introduction on how to customize e.g. the Jackson converter you can read this article from DZone about Customizing HttpMessageConverters with Spring Boot and Spring MVC.

Mapping custom MediaType with to JSON MediaType

I have a requirement to create a REST service(Jersey) which accepts header as "application/com.foo+xml" (+json incase of JSON mime type).
Is there anyway to have
#Produces("application/com.foo+xml")
without creating a custom MessageBodyWriter? Is there anyway to map "application/com.foo+xml" to "application/json"?
Just don't want to create a custom class when MediaType "application/com.foo+xml" is same as "application/xml"
I imagine you are using JAXB for handling your API messages (request/response) - if not you should look on that. Apparently what you are looking for is possible without creating custom MessageBodyWriter, according to this reference - http://jersey.576304.n2.nabble.com/Application-Specific-content-types-and-JAXB-annotations-td6380235.html - "Anything "+json" should work out of the box"... so you would simply need to define your JAXB mappings and it will generate/handle the JSON/XML representations for the #Consumes and #Produces MediaTypes you have on your API.

Android RestTemplate json deserialization

I need to write a Json client in Android for Zenfolio API. I decided to use Spring ResTemplate with MappingHttpJacksonConverter. When i do POST with "exchange" method i recieve json response with one element named "#type" that causes deserializatoon exception. Is there an annotation that tells deserializer to omit that tag? How to turn on annotation for json deserializer?
Try #JsonIgnoreProperties(ignoreUnknown=true) on your mapping classes if you want to ignore all elements that you are not interested in.
Try using #JsonIgnore ("#type"), Jackson annotations are enabled by default.
See http://wiki.fasterxml.com/JacksonAnnotations for more info.

Spring MVC - Force a controller to produce MappingJacksonJsonView(s)

Here we have a basic webapp using JSP which needs to provide a few JSON based REST service URLs.
These urls will all reside under /services and be generated by a MyRestServicesController.
The examples I see for settings up JSON based views all use ContentNegotiatingViewResolver. But it seems like overkill to me as this resolver seems meant for situations where the same URL might produce different output.
I just want my one RestServicesController to always produce MappingJacksonJsonView(s).
Is there a cleaner, more straight forward way to simply direct the controller to do this?
Is there a cleaner, more straight forward way to simply direct the controller to do this?
Yes there is. You can have a look at this sample I posted in Spring forums. In short the way I prefer to do it is through the following.
ApplicationContext:
<!-- json view, capable of converting any POJO to json format -->
<bean id="jsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
Controller
#RequestMapping("/service")
public ModelAndView getResultAsJson() {
Object jsonObj = // the java object which we want to convert to json
return new ModelAndView("jsonView", "result", jsonObj);
}
EDIT 2013: In these modern days, #skaffman's approach would be a nice alternative.
If all you need to do is output JSON, then the view layer itself is redundant. You can use the #ResponseBody annotation to instruct Spring to serialize your model directly, using Jackson. It requires less configuration than the MappingJacksonJsonView approach, and the code is less cluttered.
As long as you are using mvc:annotation-driven and Jackson is on the classpath then all you should need to do is use #ResponseBody on on your methods and the return type will be converted to JSON per Spring's standard HTTP Message Conversion functionality.
Also check out this video at around 37:00: Mastering Spring MVC.

Categories