Generating json using spring-mvc - java

I tried to generate a json response earlier using spring-mvc (annotation) . After so may failure i find out some check point :
I need to add <mvc:annotation-driven/> in my servelet mapper. although i don't know the reason.
Then I need to add #ResponseBody annotation which should bound the return value as http response as the documentation says.
And I also need add some jacson dependency.
Did i missed something?
Now i have bunch of questions
why we have to add that in my servelet xml and how this whole process is working?
As json response is most commonly used when why spring need jackson dependency to generate json?
some days ago i was doing Struts2 generating json response there was much simple.
Is there any way to do it more easily in spring-mvc .?

At first you should understand that <mvc:annotation-driven/> annotation used for many cases not only for generating json response in Spring. This annotation allow to use different annotations in Spring mvc classes like:#NumberFormat #DateFormat #Controller #Valid and of course #ResponseBody.
To generate json response you just need #ResponseBody annotation in your controller or servlet and import libraries for processing JSON.
Recently java has oun set of APIs for processing JSON as part of Java EE 7 JSR 353 actually it has clean Oracle tutorial. Also you can use third party libraries like Jackson. To process (parse, generate, transform, and query) JSON text it's necessarily to have one of this libs.
You can learn about most popular third party libraries and their performance in this article
Here you can see simple example.

If you are using jacson you can do something like:
Your Model
public class Shop {
String name;
String staffName[];
}
Your Controller
#Controller
#RequestMapping("/shop/list")
public class JSONController {
#RequestMapping(value="{name}", method = RequestMethod.GET)
public #ResponseBody Shop getShopInJSON(#PathVariable String name) {
Shop shop = new Shop();
shop.setName(name);
shop.setStaffName(new String[]{"mkyong1", "mkyong2"});
return shop;
}
}
mvc-dispatcher-servlet.xml
<context:component-scan base-package="com.example.mypackage" />
<mvc:annotation-driven />
Basically, you need check if:
Your Jackson library is existed in the project classpath
The mvc:annotation-driven is enabled
Return method annotated with #ResponseBody

Related

Add Entire Protobuf Message to Model in Spring Boot

I'm starting to play around with Spring Boot to learn how it functions for a MVC web application.
At a high-level the goal is to have a controller that will handle GET requests by issuing a request to an external gRPC server which will return a Order protobuf message. The Order data will be added to the Model and served via a template with Thymeleaf.
I am new to the Spring framework as a whole so the approach is likely incorrect but what I was doing is:
#Controller
public class OrderController {
#GetMapping("/order")
public String getOrder(#RequestParam(name = "order_number") String orderNumber, Model model) {
// Code for getting Order proto message from external server here
model.addAttribute("name", Order.getDate());
model.addAttribute("total", Order.getTotal());
model.addAttribute("number", Order.getNumber());
....
return "order";
}
}
However, this seems pretty tedious (especially for larger messages). Is there something I am missing that would allow me to add these fields en-masse?
Sorry, I cannot comment on question (SO restriction), hence asking here - cannot you just put your order object in model (rather than individual fields) and access it's fields/methods in view (Thymeleaf)?
In controller
model.addAttribute("order", order);
in view, I am not sure as I have not used Thymeleaf but should be simillar to
<span th:text="${order.getName()}" />

Angular JS & Spring REST -How to Convert JSON Model object to HttpServletRequest for a legacy app

I need to work on an enterprise legacy Java application that is developed in servlets & jsp's.Planning to convert this legacy app to a Single Page application using angular js & Spring MVC REST.
In the new development, AngularJS will be submitting the model object's (as JSON ) to Spring REST methods.
In the existing application there is a lot of code in servlets and classes (at least 2000 lines in 30 classes) written to get request parameter's using HttpServletRequest i.e., request.getParameter("name");
Is it possible to be able to inject/convert the model (JSON) object submitted by angularJs to Spring MVC REST methods into HttpServletRequest object, so that I need not change all the legacy code & classes?
Not considering to use the #RequestParam annotation in the method signature as the number of parameters are high.
Whatever JSON Object you are defining like below and which you trying to pass backend
var dataToPass={
name:"XYZ",
id:12,
selstat:[12,14]
};
For that, you need to create JAVA POJO with similar name like below
class UIData{
private String name; // Getter and Setter
private Integer id; // Getter and Setter
private List<Integer> selstat; // Getter and Setter
}
And in Spring while defining mapping in controller, you need to use annotation #ResuestBody in argument like below
#RequestMapping(value ='/mappingURL', method = RequestMethod.POST)
public #ResponseBody RsponseObject processData(#RequestBody UIData uiData, HttpServletRequest request)
throws MyException {
// Process you data
}
This will automatically convert JSON object into POJO instance.
Please go through Spring Documentation for more details.
And make sure content-type in header while passing is application/json along with Jackson library added in your dependency.

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.

REST, Spring with annotations, Jackson and handling of generic classes

I am trying to use Spring with Jackson to implement REST service using JSON as data interchange format. Now I have hit a road block with handling of generic classes in Jackson/Java. I am reading JacksonDataBinding page but I do not understand how I could use the information to help me with the issue when using Spring annotations. Given a basic response class like this, how do I make it work properly with Jackson and Spring together?
public class BasicResponseDto<ResponseDataType> {
private ResponseDataType data;
// ...
}

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