java web开发关于请求的处理转发有两种方式,
[list]
[*]一是redirect ,返回302状态和一个新Location给浏览器,让浏览器重新请求
[*] 二是requestDispatcher,可以用forward方法把请求转发给目标处理器。
grails 1.03现在的controller只提供了redirect方法,没有提供forward方法。
即使自己使用request.getRequestDispatcher("/controller/action").forward(request,response)方法或在Controller中返回ModelAndView("forward:/controller/action"),想让grails转发请求,grails也不支持,会得到404错误。
[/list] web 2.4规范filter对请求的处理方式REQUEST(外部请求)、FORWARD(内部转发)、INCLUDE(包含) 和 ERROR(错误),grails的URLMapping Filter只处理REQUEST,所以就处理不到forward的请求。
解决方法: [list]
[*]1:修改grails源码和web.xml对filter配置,不过grails的jira中已经宣称在1.1版本中会在Controller中支持forward方法
[*]2:看看grails的web.xml配置,所有的.dispatch结尾的请求会有GrailsDispatcherServlet来处理,在看看grails的源码
[/list]
所以暂时的解决方法就是返回一个ModelAndView(forwardurl),forwardurl的格式为"forward:/grails/${controllerName}/${actionName}.dispatch"
[list]
[*]一是redirect ,返回302状态和一个新Location给浏览器,让浏览器重新请求
[*] 二是requestDispatcher,可以用forward方法把请求转发给目标处理器。
grails 1.03现在的controller只提供了redirect方法,没有提供forward方法。
即使自己使用request.getRequestDispatcher("/controller/action").forward(request,response)方法或在Controller中返回ModelAndView("forward:/controller/action"),想让grails转发请求,grails也不支持,会得到404错误。
[/list] web 2.4规范filter对请求的处理方式REQUEST(外部请求)、FORWARD(内部转发)、INCLUDE(包含) 和 ERROR(错误),grails的URLMapping Filter只处理REQUEST,所以就处理不到forward的请求。
解决方法: [list]
[*]1:修改grails源码和web.xml对filter配置,不过grails的jira中已经宣称在1.1版本中会在Controller中支持forward方法
[*]2:看看grails的web.xml配置,所有的.dispatch结尾的请求会有GrailsDispatcherServlet来处理,在看看grails的源码
public class UrlMappingsFilter extends OncePerRequestFilter {
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
...
if(viewName == null || viewName.endsWith(GSP_SUFFIX) || viewName.endsWith(JSP_SUFFIX)) {
String forwardUrl = WebUtils.forwardRequestForUrlMappingInfo(request, response, info);
if(LOG.isDebugEnabled()) {
LOG.debug("Matched URI ["+uri+"] to URL mapping ["+info+"], forwarding to ["+forwardUrl+"] with response ["+response.getClass()+"]");
}
}
}
}
public class WebUtils extends org.springframework.web.util.WebUtils {
...
public static String forwardRequestForUrlMappingInfo(HttpServletRequest request, HttpServletResponse response, UrlMappingInfo info) throws ServletException, IOException {
return forwardRequestForUrlMappingInfo(request, response, info, Collections.EMPTY_MAP);
}
public static String forwardRequestForUrlMappingInfo(HttpServletRequest request, HttpServletResponse response, UrlMappingInfo info, Map model) throws ServletException, IOException {
GrailsWebRequest webRequest = (GrailsWebRequest) RequestContextHolder.currentRequestAttributes();
String forwardUrl = buildDispatchUrlForMapping(info);
//populateParamsForMapping(info);
RequestDispatcher dispatcher = request.getRequestDispatcher(forwardUrl);
populateWebRequestWithInfo(webRequest, info);
exposeForwardRequestAttributes(request);
exposeRequestAttributes(request, model);
dispatcher.forward(request, response);
return forwardUrl;
}
public static String buildDispatchUrlForMapping(UrlMappingInfo info) {
final StringBuffer forwardUrl = new StringBuffer();
if (info.getViewName() != null) {
String viewName = info.getViewName();
forwardUrl.append(SLASH).append(viewName);
}
else {
// GRAILS_SERVLET_PATH="/grails" SLASH='/' GRAILS_DISPATCH_EXTENSION=".dispatch"
forwardUrl.append(GrailsUrlPathHelper.GRAILS_SERVLET_PATH);
forwardUrl.append(SLASH)
.append(info.getControllerName());
if(!StringUtils.isBlank(info.getActionName())) {
forwardUrl.append(SLASH)
.append(info.getActionName());
}
forwardUrl.append(GrailsUrlPathHelper.GRAILS_DISPATCH_EXTENSION);
}
return forwardUrl.toString();
}
}
按照grails处理规则,只要forward的url为/grails/controller/action.dispatch,grails就可以处理了。
[/list]
所以暂时的解决方法就是返回一个ModelAndView(forwardurl),forwardurl的格式为"forward:/grails/${controllerName}/${actionName}.dispatch"