web-dev-qa-db-fra.com

Renvoyer JSON ou une vue à partir d'un contrôleur MVC Spring

Je souhaite renvoyer une vue d'un contrôleur Spring MVC en fonction de la logique. Si une erreur se produit, je souhaite renvoyer JSON, sinon une vue HTML. Cela ressemble à ASP.NET MVC ActionResult, où vous pouvez renvoyer n'importe quel type de vue et le résultat sera rendu, sans que cela dépende du type de contenu envoyé dans la demande. Je ne trouve aucun exemple de cela.

15
Mike Flynn

J'ai réalisé ceci avec ce qui suit.

@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 Fonction qui effectue l'appel

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


                    }
                });
17
Mike Flynn

Au cas où vous voudriez retourner Json, vous pouvez effectuer les opérations suivantes:

@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);
      }

Je ne suis pas sûr que c'est ce que vous vouliez faire, mais juste au cas où .... :)

6
danny.lesnik

Programmez votre contrôleur pour renvoyer un nom de vue logique différent en fonction d'une condition. Par exemple:

@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;
}

Configurez les résolveurs de vue pour résoudre le nom de vue "error" en vue JSON. Spring propose de nombreuses façons de configurer le nom de la vue pour afficher le mappage, notamment:

Par exemple, pour utiliser 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
Chin Huang

Rien ne vous empêche de renvoyer un objet View réel directement à partir de votre méthode de contrôleur - il ne doit pas nécessairement s'agir d'un nom de vue. Ainsi, votre contrôleur peut construire un objet View en utilisant sa propre logique et le renvoyer, avec ou sans encapsulation dans un objet ModelAndView.

C’est probablement plus simple que d’essayer de persuader le framework ViewResolver de le faire pour vous, bien que cela fonctionne également.

2
skaffman

Peut-être que vous pouvez regarder ResolveBundleViewResolver , qui vous permet de mélanger des vues. Les docs donnent des informations sur la manière de l’utiliser. 

D'après la documentation (par exemple, mélanger les carreaux et jstl, mais devrait s'appliquer également aux autres) ...

fichier de contexte

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