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方法就可以 

你可能感兴趣的:(jsp,Web,servlet,grails,groovy)