`
bloodwolf_china
  • 浏览: 129759 次
社区版块
存档分类
最新评论

grails中RequestDispatch的forward终极解决方法

阅读更多
  在使用grails中发现,controller本身没有提供转发请求的方法,之后查看源码后发现按照grails的DispatchServlet的格式即/grails/controllerName/actionName.dispatch这样的URI,是可以转发的。
但发现如果在gsp或jsp中调用request.getRequestDispatcher(uri).forward(request,response),页面就会在forward的那行代码抛出NullPointerException。最近一直在研究其源码,终于找到了解决方法,这其实是grails的一个小bug吧。
首先GrailsWebRequestFilter把当前request放在ThreadLocal中,在经过UrlMappingsFilter通过查找Url映射,看是否有满足条件的Controller,如果有设置GrailsWebRequest中的Controller和action值,并转发到GrailsDispatcherServlet处理。在gsp/jsp中做转发,当前GrailsWebRequest中的Controller和action值都是null

import javax.servlet.http.HttpServletRequest
import javax.servlet.ServletException
import org.springframework.web.context.request.RequestContextHolder;
import org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequest
import org.codehaus.groovy.grails.web.servlet.GrailsUrlPathHelper
import org.codehaus.groovy.grails.web.util.WebUtils
import org.apache.commons.lang.StringUtils
import javax.servlet.http.HttpServletResponse


public class RequestDispatchUtils {

	public static void forward(HttpServletRequest request,HttpServletResponse response,String controller,String action, Map params)throws ServletException, IOException {
        GrailsWebRequest webRequest = RequestContextHolder.currentRequestAttributes();
        webRequest.setControllerName(controller)
        webRequest.setActionName(action)
        if(params)
          webRequest.getParams().putAll(params)  
        request.getRequestDispatcher(buildDispatchUrl(controller,action)).forward(request,response)
	}

    private static String buildDispatchUrl(String contoller,String action) {
        final StringBuffer forwardUrl = new StringBuffer();
        
        forwardUrl.append(GrailsUrlPathHelper.GRAILS_SERVLET_PATH);
        forwardUrl.append(WebUtils.SLASH)
                          .append(contoller);

        if(!StringUtils.isBlank(action)) {
            forwardUrl.append(WebUtils.SLASH)
                      .append(action);
        }
        forwardUrl.append(GrailsUrlPathHelper.GRAILS_DISPATCH_EXTENSION);

        return forwardUrl.toString();
    }


}
//在jsp或controller中直接调用RequestDispatchUtils的forward方法就可以 
2
0
分享到:
评论
2 楼 bloodwolf_china 2009-02-06  
引用
在save action里面,如果我用这个forward方法

这个类的forward的方法是把当前请求转发到另一个Controller中处理,提供了两个参数String controller,String action
如果在同一个controller中,不需要forward,直接调用另一个方法就可以了。
1 楼 seanwon 2009-02-03  
兄弟,有一点小问题。

我们拿Book的domain类来举例,我创建以后save,在save action里面,如果我用这个forward方法,那么就会被提示没有save.gsp。因为默认的action和view的映射是根据名字的。

而原来用redirect(action:show)是会到show.gsp页面呈现的。

除了重新创建一个view以外,还有别的解决方案嘛?

相关推荐

Global site tag (gtag.js) - Google Analytics