spring json not working - java

I created a controller with method handler as
#RequestMapping( value = {"/membersjson"},method = RequestMethod.GET)
public #ResponseBody String getMembers(Model model) {
List<Member> members = memberService.getMembers();
model.addAttribute("members",members);
return "jsontemplate";
}
<bean id="jsontemplate"
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
I expect the out put to be in json but instead the output is "jsontemplate" instead. Can some one please explain the reason. thanks in advance.

MappingJacksonJsonView, or any other view or view resolver bean, is irrelevant when you're using #ResponseBody. Instead, Spring will try to convert the return value of your method directly into a response. In this case, it's decided to turn it into a String response.
First make, sure you've declared <mvc:annotation-driven/> in your context, and that Jackson is available on the classpath. Also ensure that the browser is sending application/json in its Accept header.

You shouldn't be returning the string "jsontemplate"; you should return either the List<Member> or the Model. The json mapping should occur automatically.

Related

Model model in Controller's method parameters in Spring MVC

This may be a very naive question to ask but I would like to know as a beginner in Spring MVC framework instead of returning ModelAndView Object can we just return a jsp name from a Controller's method definitions ? Also Apparently all the methods seem to take Model model as a argument. What does they mean ?
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, Model model) {
logger.debug("Entering renderShoeStoreApplication method");
//model.addAttribute("orderList", orderList);
logger.debug("Exiting renderShoeStoreApplication method");
return "home";
}
Instead of we could also write I suppose
/*
#RequestMapping(value = "/", method = RequestMethod.GET)
public ModelAndView home(Locale locale, Model model) {
logger.debug("Entering renderShoeStoreApplication method");
//model.addAttribute("orderList", orderList);
logger.debug("Exiting renderShoeStoreApplication method");
ModelAndView homeModel = new ModelAndView("home");
return homeModel ;
}*/
Please explain the basics . Thanks in advance.
i think you have got two question
All the methods seem to take Model model as a argument
this is necessarily not required, you can get http request as param and you can derive your model from the request parameters. eventually spring mvc does this for you to make the work much simpler using binding-result after bean validation.
#RequestMapping(value = "/", method = RequestMethod.GET)
public String home(Locale locale, HttpRequest request) {
String name = request.getParamter("name");
// you can manually derive your model here
}
can we just return a jsp name from a Controller's method definitions ?
you can pass the just jsp name in your controller method, provided if you have configured your view resolver to handled this.
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/views/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
if you return string from controller, by default controller direct to view resolver to resolve the view. pls check this SO post
You can go through the below resources to understand the basics of Spring MVC, first and foremost the official docs from spring MVC community and some of the quick heads up of the POC's using below links
http://earldouglas.com/publications/barebones-spring-mvc/
http://spring.io/guides/gs/serving-web-content/
http://www.mkyong.com/tutorials/spring-mvc-tutorials/
Why model is passed as a parameter to controller method and what is the purpose of ModelView object?..All such questions will get answered once you will get the basic understanding of Spring MVC architecture.
And Yes, In the event that there isn't any data to be returned by the method, the controller method can simply return a String that represents the view that should be rendered.

Automatic conversion of JSON form parameter in Spring MVC 4.0

I am trying to build a Spring MVC controller which will receive a POSTed form with a parameter in JSON format, and have Spring automatically convert it to a Java object.
Request content type is application/x-www-form-urlencoded
The name of the parameter that contains a JSON string is data.json
This is the controller:
#Controller
public class MyController {
#RequestMapping(value = "/formHandler", method = RequestMethod.POST)
public #ResponseBody String handleSubscription(
#RequestParam("data.json") MyMessage msg) {
logger.debug("id: " + msg.getId());
return "OK";
}
}
And this is what the MyMessage object looks like:
public class MyMessage {
private String id;
// Getter/setter omitted for brevity
}
Perhaps not surprisingly, posting a form with parameter data.json={"id":"Hello"} results in HTTP error 500 with this exception:
org.springframework.beans.ConversionNotSupportedException:
Failed to convert value of type 'java.lang.String' to required type 'MyMessage'
nested exception is java.lang.IllegalStateException:
Cannot convert value of type [java.lang.String] to required type [MyMessage]: no matching editors or conversion strategy found
If I read the MappingJackson2HttpMessageConverter docs correctly, Jackson JSON conversion is triggered by Content-Type application/json, which I obviously cannot use since this is a form POST (and I don't control the POSTing part).
Is it possible to get Spring to convert the JSON string into an instance of MyMessage, or should I just give up, read it as a String and perform the conversion myself?
Spring invokes your #RequestMapping methods with reflection. To resolve each argument it's going to pass to the invocation, it uses implementations of HandlerMethodArgumentResolver. For #RequestParam annotated parameters, it uses RequestParamMethodArgumentResolver. This implementation binds a request parameter to a single object, typically a String or some Number type.
However, your use case is a little more rare. You rarely receive json as a request parameter, which is why I think you should re-think your design, but if you have no other choice, you need to register a custom PropertyEditor that will take care of converting the request parameter's json value into your custom type.
Registration is simple in an #InitBinder annotated method in your #Controller class
#InitBinder
public void initBinder(WebDataBinder dataBinder) {
dataBinder.registerCustomEditor(MyMessage.class, new PropertyEditorSupport() {
Object value;
#Override
public Object getValue() {
return value;
}
#Override
public void setAsText(String text) throws IllegalArgumentException {
value = new Gson().fromJson((String) text, MyMessage.class);
}
});
}
In this particular case, we don't need all the methods of the PropertyEditor interface, so we can use PropertyEditorSupport which is a helpful default implementation of PropertyEditor. We simply implement the two methods we care about using whichever flavor of JSON parser we want. I used Gson because it was available.
When Spring sees that it has a request parameter that you requested, it will check the parameter type, find the type MyMessage and look for a registered PropertyEditor for that type. It will find it because we registered it and it it will then use it to convert the value.
You might need to implement other methods of PropertyEditor depending on what you do next.
My recommendation is to never send JSON as a request parameter. Set your request content type to application/json and send the json as the body of the request. Then use #RequestBody to parse it.
You can also use #RequestPart like this:
#RequestMapping(value = "/issues", method = RequestMethod.POST, headers = "Content-Type=multipart/form-data")
public String uploadIssue(#RequestParam("image") MultipartFile file, #RequestPart("issue") MyMessage issue)

How do get the list from #ResponseBody in JSP?

I use Spring MVC, I have controller with a method:
#RequestMapping(value = "/listReader", method = RequestMethod.POST)
public #ResponseBody
List<Reader> getListReader(ModelMap model) {
return libraryService.getAllReaders();
}
But I do not know:
How can use list (that I get from method getListReader by #ResponseBody) in JSP?
How can I get list in JSP?
How do to display a list in JSP-page?
How do to get the list from #ResponseBody in JSP?
Give an example, please.
You can't. #ResponseBody is basically telling Spring: take the object I (method) return and use any serializer you have that supports it and write it directly to the body of the HTTP response. There's no JSP involved here.
Instead you should add the list to the model and return the String view name of your JSP.
#RequestMapping(value = "/listReader", method = RequestMethod.POST)
public String getListReader(ModelMap model) {
model.addAttribute("someKey", libraryService.getAllReaders());
return "my-jsp";
}
then you can use EL in the JSP to retrieve it
<h3>${someKey}</h3>
Use JSTL to iterate over it.
#RequestMapping(value = "/listReader", method = RequestMethod.POST)
That defines an Endpoint.
I would suggest using RequestMethod.GET than RequestMethod.POST, since you want something from the server not POSTING something to the server.
On the other Hand, if you want to use that information on a JSP, there are two ways:
1) Some view could consume that information via a http-GET-Request like $.get in jQuery or ajax. After you got the data, you can insert it in your HTML
2) Instead of using ajax you could display it directly on the page.
Then, you have to put your List into a Model, which you can acces on your JSP with Expression Language. Then you have to remove the #ResponseBody and return an according view instead.

Is there any way to configure spring mvc to assume a content-type?

I have a method to which I want to post some json data, that looks like this
#RequestMapping(value = "/m1", method = RequestMethod.POST)
public Object m1(#RequestBody Map<String, ?> body) {
// do something
}
This works great when I set the content-type header to application/json when I post, but fails with an error if I don't (it cannot deserialize the post body into the map because it doesn't know how)
What would I have to configure in spring to make it use application/json as a default when no header is specified?
The class that converts the JSON to your object is called an HttpMessageConverter. I assume you are using the default Jackson one that comes with Spring. You can write a custom MessageConverter, that will always return true in it's supports method with your response object type and then just call the Jackson httpconverter in your readInternal and writeInternal methods. If you do this however, be careful, as once it's registered in your requesthandler, it will be asked on all #ResponseBody and #RequestBody requests.

Access Model object in a JSP without using the ModelAndView object?

I am using spring mvc with Annotations, see the following snippet
#RequestMapping(value = "/configuration/", method = RequestMethod.GET)
public MyModel viewConfiguration() {
The problem I am having accessing the 'MyModel' class in my JSP.
How can I do this, without using the ModelAndView object?
This shorthand syntax means that MyModel becomes a model attribute named myModel (i.e. class name with the first letter decapitalized).
View name is inferred from the URL.
See also:
15.3.2.3 Supported handler method arguments and return types
15.10.3 The View - RequestToViewNameTranslator
You could set MyModel as a request attribute to be accessed in your JSP. I'm curious, why don't you want to use ModelAndView? After all, it does what you want to do here, which displays the view and provides a container to hold your objects you want to reference in your view.
By the way, if this is an Ajax call, you will need to add #ResponseBody to the API so that your javascript can read the response in the callback function:-
#RequestMapping(value = "/configuration/", method = RequestMethod.GET)
public #ResponseBody MyModel viewConfiguration() {
...
}

Categories

Resources