【发布时间】:2011-02-07 00:54:16
【问题描述】:
我想根据逻辑从 Spring MVC 控制器返回一个视图。如果发生错误,我想返回 JSON,如果没有,则返回 HTML 视图。这就像 ASP.NET MVC ActionResult,您可以在其中返回任何类型的视图,它将呈现结果,并且不依赖于请求中发送的内容类型。我找不到任何这样的例子。
【问题讨论】:
标签: json spring spring-mvc
我想根据逻辑从 Spring MVC 控制器返回一个视图。如果发生错误,我想返回 JSON,如果没有,则返回 HTML 视图。这就像 ASP.NET MVC ActionResult,您可以在其中返回任何类型的视图,它将呈现结果,并且不依赖于请求中发送的内容类型。我找不到任何这样的例子。
【问题讨论】:
标签: json spring spring-mvc
我通过以下方式实现了这一点。
@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函数
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) {
}
});
【讨论】:
if (true) - 那么 JSON 什么时候返回?
以防万一您想在异常时返回 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);
}
我不确定这是你想要做的,但以防万一...... :)
【讨论】:
对控制器进行编程以根据条件返回不同的逻辑视图名称。例如:
@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;
}
配置视图解析器以将视图名称 "error" 解析为 JSON 视图。 Spring提供了多种方式来配置视图名到视图映射,包括:
例如,使用 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>
【讨论】:
没有什么可以阻止您直接从控制器方法返回实际的 View 对象 - 它不必是视图名称。因此,您的控制器可以使用自己的逻辑构造一个 View 对象,然后将其返回,无论是否包含在 ModelAndView 对象中。
这可能比试图说服ViewResolver 框架不要为您执行此操作更简单,尽管这也可以。
【讨论】:
也许你可以看看ResolveBundleViewResolver,它可以让你混合视图。 docs 提供了一些关于如何使用它的信息。
来自文档(示例是混合瓷砖和 jstl,但也应适用于其他人)...
上下文文件
<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
...
【讨论】:
为了扩展 Chin Huang 的答案,这对我有用。无需配置。
response.setStatus(500);
return new ModelAndView(new MappingJacksonJsonView(), model);
这将自动将模型转换为 JSON 并写入响应。
这里模型的类型是Map<String,Object>,响应的类型是HttpServletResponse
【讨论】: