从 Spring MVC 控制器返回 JSON 或视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4917329/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:44:54  来源:igfitidea点击:

Return JSON or View from Spring MVC Controller

jsonspringspring-mvc

提问by Mike Flynn

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.

我想根据逻辑从 Spring MVC 控制器返回一个视图。如果发生错误,我想返回 JSON,如果没有,则返回 HTML 视图。这就像 ASP.NET MVC ActionResult,您可以在其中返回任何类型的视图并呈现结果,并且它不依赖于请求中发送的内容类型。我找不到任何这方面的例子。

回答by Mike Flynn

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

jsonview.java

public class JsonView {

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

        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

进行调用的 JS 函数

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) {


                    }
                });

回答by danny.lesnik

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

以防万一并且您想在异常时返回 Json,您可以执行以下操作:

@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.... :)

我不确定这是你想要做的,但以防万一...... :)

回答by Chin Huang

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:

配置视图解析器以将视图名称解析为"error"JSON 视图。Spring 提供了多种配置视图名称到视图映射的方式,包括:

For example, to use BeanNameViewResolver:

例如,要使用 BeanNameViewResolver:

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

<bean class="org.springframework.web.servlet.view.BeanNameViewResolver">
  <property name="order" value="1"/>
</bean>

回答by skaffman

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

没有什么可以阻止您View直接从控制器方法返回实际对象 - 它不必是视图名称。所以你的控制器可以View使用它自己的逻辑构造一个对象,并返回它,无论是否包装在一个ModelAndView对象中。

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

这可能比试图说服ViewResolver框架为您执行此操作更简单,尽管这也能奏效。

回答by Raghuram

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

也许您可以查看ResolveBundleViewResolver,它允许您混合视图。该文档就如何使用此的一些信息。

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

来自文档(示例是混合瓷砖和 jstl,但也应适用于其他人)...

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
...

回答by arahant

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

为了扩展 Chin Huang 的回答,这对我有用。无需配置。

response.setStatus(500);
return new ModelAndView(new MappingHymansonJsonView(), 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

这将自动将模型转换为 JSON 并写入响应。这里模型是类型Map<String,Object>,响应是类型HttpServletResponse