如何在一个spring mvc方法中处理X​​mlHttpRequest(AJAX)和常规http请求?

时间:2011-01-20 17:26:16

标签: ajax spring-mvc

目前我的解决方案是

对于AJAX:

@RequestMapping(value = "/verify", method = {RequestMethod.GET},
    headers = "x-requested-with=XMLHttpRequest")
    public 
    @ResponseBody userTO
    void verifyForXHR(@RequestParam(required = true) String code,
            HttpServletRequest request, HttpServletResponse response) {
        try {
            UserTO userTO = new SomeService().verifyEmail(code);
            return userTO;
        } catch (ExceptionABC ex) {
            response.setStatus(response.SC_BAD_REQUEST);
            return null;
        } catch (RuntimeException ex) {
              response.setStatus(response.SC_INTERNAL_SERVER_ERROR);
              return null;
        }

    }

对于常规的http请求:

@RequestMapping(value = "/verify", method = {RequestMethod.GET})
    public ModelAndView verify(@RequestParam(required = true) String code) {
        //get user to
        try {
            ModelAndView mav = new ModelAndView();
            UserTO userTO = new SomeService().verifyEmail code);

            mav.setViewName("somegoodpage");
            mav.addObject("user", userTO);
            return mav;
        } catch (ExceptionABC ex) {
                logger.error(ex, ex);
                ModelAndView mav = new ModelAndView("error page);
                return mav;
            }

        } catch (RuntimeException ex) {
            logger.error(ex.toString(), ex);
            ModelAndView mav = new ModelAndView("another error page");
            return mav;
        }

    }

如果我可以将它们合并到一个方法中,那将是超级的。请注意,他们有不同的退货类型。 AJAX请求的调用者是JavaScript,因此它需要JSON作为http响应体媒体类型。对于常规的http请求,它需要返回一个视图(页面)。任何建议将不胜感激!

2 个答案:

答案 0 :(得分:1)

要在一个方法中使用它,您可以通过采用一个额外的参数@RequestHeader(value = "x-requested-with:XMLHttpRequest", required = false) String ajax来区分这两个方法。然后,您可以检查if (ajax == null)与否,并采取相应的措施。

答案 1 :(得分:0)

不要在控制器中以这种方式处理异常。构建一个适当的ajax感知异常解析器,然后你的控制器方法将是一个衬里。我将AbstractHandlerExceptionResolver子类化基本上做了这个:

@Override
public ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object o, Exception exception) {
    int code = getResponseCode(exception);

    applyStatusCodeIfPossible(request, response, code);

    ExceptionInfo info = createErrorInfo(exception);
    if ("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) {
        return new ModelAndView(jsonView, MODEL_KEY, info);
    }
    else if ((code == 403 || code == 401) && SecurityContextHolder.getContext().getAuthentication().getAuthorities().contains(ANONYMOUS) == false) {
        return new ModelAndView(LOGIN_REDIRECT);
    }
    else {
        return new ModelAndView(getViewName(code), MODEL_KEY, info);
    }
}

之后你只需要

@RequestMapping(value = "/verify", method = {RequestMethod.GET}, headers = "x-requested-with=XMLHttpRequest")
@ResponseBody public userTO verifyForXHR(@RequestParam String code) {
    return new SomeService().verifyEmail(code);
}

@RequestMapping(value = "/verify", method = {RequestMethod.GET})
public ModelAndView verify(@RequestParam String code) {
    return new ModelAndView("somegoodpage", "user", new SomeService().verifyEmail(code));
}