Вернуть JSON или View из Spring MVC Controller - PullRequest
16 голосов
/ 07 февраля 2011

Я хочу вернуть представление из контроллера Spring MVC в зависимости от логики.Если возникает ошибка, я хочу вернуть JSON, если нет, HTML-представление.Это похоже на ASP.NET MVC ActionResult, где вы можете вернуть любой вид представления, и он будет отображать результат, и он не будет зависеть от типа содержимого, отправляемого в запросе.Я не могу найти никаких примеров этого.

Ответы [ 6 ]

17 голосов
/ 11 февраля 2011

Я достиг этого с помощью следующего.

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


                    }
                });
6 голосов
/ 07 февраля 2011

На всякий случай, и вы хотите вернуть 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);
      }

Я не уверен, что это то, что вы хотели сделать, но на всякий случай ....:)

4 голосов
/ 07 февраля 2011

Запрограммируйте контроллер на возврат другого логического имени представления в зависимости от условия.Например:

@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-файлы определения компонента,
  • ResourceBundleViewResolver который читает файлы свойств, и
  • BeanNameViewResolver , который ищет в контексте приложения выполняющегося DispatcherServlet для компонента, имя которого совпадает с именем представления.

Например, чтобы использовать 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>
2 голосов
/ 07 февраля 2011

Ничто не мешает вам возвращать фактический View объект непосредственно из вашего метода контроллера - это не обязательно должно быть имя представления.Таким образом, ваш контроллер может сконструировать объект View, используя свою собственную логику, и вернуть его, с или без включения в ModelAndView объект.

Это, вероятно, проще, чем пытаться убедить структуру ViewResolverделать это для вас, хотя это также сработало бы.

0 голосов
/ 13 января 2013

Чтобы расширить ответ Чин Хуана, вот что работает для меня. Конфигурация не требуется.

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

Это автоматически преобразует модель в JSON и записывает в ответ. Здесь модель имеет тип Map<String,Object>, а ответ имеет тип HttpServletResponse

0 голосов
/ 07 февраля 2011

Возможно, вы можете взглянуть на ResolveBundleViewResolver , который позволяет смешивать представления. документы дают некоторую информацию о том, как это использовать.

Из документов (пример - это смешивание плиток и 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
...
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...