Я хочу вернуть представление из Spring MVC Controller в зависимости от логики. Если возникает ошибка, я хочу вернуть JSON, если нет, представление HTML. Это похоже на ASP.NET MVC ActionResult, где вы можете вернуть какой-либо вид, и он отобразит результат, и он не будет зависеть от типа содержимого, отправляемого в запросе. Я не могу найти примеров этого.
Возврат JSON или Просмотр из Spring MVC-контроллера
Ответ 1
Я достиг этого со следующим.
@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) {
}
});
Ответ 2
На всякий случай, и вы хотите вернуть 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);
}
Я не уверен, что это то, что вы хотели сделать, но на всякий случай....:)
Ответ 3
Запрограммируйте ваш контроллер для возврата другого логического вида в зависимости от состояния. Например:
@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 предоставляет множество способов настройки имени представления для просмотра сопоставления, в том числе:
- XmlViewResolver, который читает XML файлы определения bean,
- ResourceBundleViewResolver, который считывает файлы свойств и
- BeanNameViewResolver, который смотрит в контексте приложения исполняемого DispatcherServlet для bean с тем же именем, что и имя представления.
Например, для использования 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>
Ответ 4
Нет ничего, что помешало бы вам вернуть фактический объект View
непосредственно из вашего метода контроллера - это не должно быть именем вида. Таким образом, ваш контроллер может построить объект View
, используя свою собственную логику, и вернуть это, с или без обертывания в объект ModelAndView
.
Это, вероятно, проще, чем пытаться убедить структуру ViewResolver
сделать это за вас, хотя это тоже сработает.
Ответ 5
Возможно, вы можете посмотреть 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
...
Ответ 6
Чтобы продлить ответ Чин Хуан, вот что работает для меня. Конфигурация не требуется.
response.setStatus(500);
return new ModelAndView(new MappingJacksonJsonView(), model);
Это автоматически преобразует модель в JSON и напишет ответ.
Здесь модель имеет тип Map<String,Object>
и ответ имеет тип HttpServletResponse