Return JSON or View from Spring MVC Controller

2020-05-16 02:41发布

I am wanting to return a view from a Spring MVC Controller depending on logic. If an error occurs I want to return JSON, if not, an HTML view. This is like ASP.NET MVC ActionResult, where you can return any kind of view and it will render the result, and it won't depend on the content-type being sent in the request. I can't find any examples of this.

6条回答
闹够了就滚
2楼-- · 2020-05-16 02:51

Program your controller to return a different logical view name depending on a condition. For example:

@RequestMapping(value="/hello/{name}", method=RequestMethod.GET)
public ModelAndView hello(@PathVariable String name) {
    String viewName = (name.length() > 1) ? "hello" : "error";
    ModelAndView mav = new ModelAndView(viewName);
    mav.addObject("name", name);
    return mav;
}

Configure the view resolvers to resolve the view name "error" to the JSON view. Spring provides many ways to configure the view name to view mapping, including:

For example, to use BeanNameViewResolver:

<bean name="error" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
  <property name="order" value="1"/>
</bean>
查看更多
▲ chillily
3楼-- · 2020-05-16 02:53

Perhaps you can look at ResolveBundleViewResolver, which allows you to mix views. The docs give some info on how to use this.

From the docs (example is to mix tiles and jstl, but should apply for others as well)...

context file

<bean id="viewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
  <property name="basename" value="views"/>
</bean>

views.properties

...
welcomeView.(class)=org.springframework.web.servlet.view.tiles2.TilesView
welcomeView.url=welcome (this is the name of a Tiles definition)

vetsView.(class)=org.springframework.web.servlet.view.tiles2.TilesView
vetsView.url=vetsView (again, this is the name of a Tiles definition)

findOwnersForm.(class)=org.springframework.web.servlet.view.JstlView
findOwnersForm.url=/WEB-INF/jsp/findOwners.jsp
...
查看更多
beautiful°
4楼-- · 2020-05-16 02:55

To extend Chin Huang's answer, here is what works for me. No configuration required.

response.setStatus(500);
return new ModelAndView(new MappingJacksonJsonView(), model);

This will automatically convert the model into JSON and write to response. Here model is of type Map<String,Object> and response is of type HttpServletResponse

查看更多
Melony?
5楼-- · 2020-05-16 03:06

There's nothing to prevent you from returning an actual View object directly from your controller method - it doesn't have to be a view name. So your controller can construct a View object using its own logic, and return that, with or without being wrapped in a ModelAndView object.

This is probably simpler than trying to persuade the ViewResolver framework from doing this for you, although that would work as well.

查看更多
贼婆χ
6楼-- · 2020-05-16 03:09

I achieved this with the following.

@RequestMapping(value="/users", method=RequestMethod.POST)
public Object index(@RequestBody SearchUsersViewModel model, HttpServletResponse response) {

    model.setList(userService.getUsers(model));

    if(true)
    {
        return new ModelAndView("controls/tables/users", "model", model);
    }
    else
    {
        return JsonView.Render(model, response);
    }    
}

JsonView.java

public class JsonView {

    public static ModelAndView Render(Object model, HttpServletResponse response)
    {
        MappingJacksonHttpMessageConverter jsonConverter = new MappingJacksonHttpMessageConverter();

        MediaType jsonMimeType = MediaType.APPLICATION_JSON;


        try {
            jsonConverter.write(model, jsonMimeType, new ServletServerHttpResponse(response));
        } catch (HttpMessageNotWritableException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        return null;
    }
}

JS Function that makes the call

config.request = $
                .ajax({
                    url : url,
                    data : $.toJSON(def.data),
                    type : def.type,
                    dataType : def.dataType,
                    processData : true,
                    contentType : def.contentType,
                    success : function(data) {

                        try {
                            var json = data;
                            if (typeof data === "String" || typeof data == "string") {
                                json = (eval('(' + data + ')'));
                            }
                            if ('object' === typeof json) {
                                if (json.Validation && json.Validation.Errors.length > 0) {

                                    $.each(json.Validation.Errors, function() {
                                        // Error Code Check
                                    });

                                    // Error Callback
                                    if (typeof (def.errorCallback) == 'function') {
                                        def.errorCallback(json);
                                    }
                                } else {
                                    def.callback(data);
                                }
                            } else {
                                def.callback(data);
                            }
                        } catch (e) {
                            def.callback(data);
                            // Hide Loading
                        }
                    },
                    error : function(data) {


                    }
                });
查看更多
唯我独甜
7楼-- · 2020-05-16 03:10

Just in case and you want to return Json on exception you can do the following:

@ExceptionHandler(Exception.class)
    @ResponseBody
      public void handleIOException(Exception exception,HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("application/json");
        String json = "{\"Name\": 50}";
        PrintWriter out=    response.getWriter();
        out.write(json);
      }

I'm not sure that this is what you wanted to do, but just in case.... :)

查看更多
登录 后发表回答