2013-02-15 89 views
1

我试图用java/jsp中的过滤器过滤出一个名为'reason'的查询参数。HttpServletRequestWrapper被删除的参数仍然显示出来

基本上,过滤器就位以确保用户输入查看页面的“原因”。如果他们没有,则需要将他们重定向到“输入原因”页面。一旦他们输入了有效的理由,他们可以继续到他们要求的页面。

因此,它的基础工作。但是,“原因”是通过查询参数(即GET参数)发送的。一旦用户选择了一个原因,原因参数将被转发到他们想要查看的页面上。这是一个问题,因为检查原始参数是否存在是筛选器确定用户是否可以继续前进的主要方法之一。

我试过扩展HttpServletRequestWrapper,并且为了去除'reason'参数而覆盖了一堆方法(即getPameter等)。但是,我一直无法看到参数被删除。一旦过滤器转发到请求的页面,'reason'参数将始终在查询字符串中(即浏览器url栏中的url)作为GET参数。

我的过滤器类的样子:

public final class AccessRequestFilter implements Filter { 

    public class FilteredRequest extends HttpServletRequestWrapper { 

     public FilteredRequest(ServletRequest request) { 
      super((HttpServletRequest)request); 
     } 

     @Override 
     public String getParameter(String paramName) { 
      String value = super.getParameter(paramName); 

      if ("reason".equals(paramName)) { 
       value = null; 
      } 

      return value; 
     } 

     @Override 
     public String[] getParameterValues(String paramName) { 
      String[] values = super.getParameterValues(paramName); 

      if ("reason".equals(paramName)) { 
       values = null; 
      } 

      return values; 
     } 

     @Override 
     public Enumeration<String> getParameterNames() { 
      return Collections.enumeration(getParameterMap().keySet()); 
     } 

     @Override 
     public Map<String, String[]> getParameterMap() {    
      Map<String, String[]> params = new HashMap<String, String[]>(); 
      Map<String, String[]> originalParams = super.getParameterMap(); 

      for(Object o : originalParams.entrySet()) { 
       Map.Entry<String, String[]> pairs = (Map.Entry<String, String[]>) o; 
       params.put(pairs.getKey(), pairs.getValue()); 
      } 

      params.remove("reason"); 

      return params; 
     } 

     @Override 
     public String getQueryString() { 
      String qs = super.getQueryString(); 

      return qs.replaceAll("reason=", "old_reason="); 
     } 

     @Override 
     public StringBuffer getRequestURL() { 
      String qs = super.getRequestURL().toString(); 

      return new StringBuffer(qs.replaceAll("reason=", "old_reason=")); 
     } 
    } 

    private FilterConfig filterConfig = null; 
    private static final Logger logger = MiscUtils.getLogger(); 

    public void init(FilterConfig filterConfig) throws ServletException { 
     this.filterConfig = filterConfig; 
    } 

    public void destroy() { 
     this.filterConfig = null; 
    } 

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 
     logger.debug("Entering AccessRequestFilter.doFilter()"); 

     HttpServletRequest httpRequest = (HttpServletRequest) request; 
     HttpServletResponse httpResponse = (HttpServletResponse) response; 
     HttpSession session = httpRequest.getSession(); 

     boolean canView = false; 
     long echartAccessTime = 0L; 
     String demographicNo = ""; 
     String reason = ""; 
     Date current = new Date(); 

     String user_no = (String) session.getAttribute("user"); 

     ProgramProviderDAO programProviderDAO = (ProgramProviderDAO)SpringUtils.getBean("programProviderDAO"); 
     ProgramQueueDao programQueueDao = (ProgramQueueDao)SpringUtils.getBean("programQueueDao"); 

     // Check to see if user has submitted a reason 
     reason = request.getParameter("reason"); 
     demographicNo = request.getParameter("demographicNo"); 
     Long demographicNoAsLong = 0L; 
     try { 
      demographicNoAsLong = Long.parseLong(demographicNo); 
     } catch (Exception e) { 
      logger.error("Unable to parse demographic number.", e); 
     } 

     if (reason == null) { 
      // If no reason was submitted, see if user still has time remaining on previous submission (if there was one) 
      try { 
       echartAccessTime = (Long)session.getServletContext().getAttribute("echartAccessTime_" + demographicNo); 
      } catch (Exception e) { 
       logger.warn("No access time found"); 
      } 

      if (current.getTime() - echartAccessTime < 30000) { 
       canView = true; 
      } 
     } else if (!reason.equals("")) { 
      // TODO: validate reason 
      canView = true; 
      session.getServletContext().setAttribute("echartAccessTime_" + demographicNo, current.getTime()); 
      String ip = request.getRemoteAddr(); 
      // Log the access request and the reason given for access 
      LogAction.addLog(user_no, "access", "eChart", demographicNo, ip, demographicNo, reason); 
     } 

     if (!canView) { 
      // Check if provider is part of circle of care 
      List<Long> programIds = new ArrayList<Long>(); 

      List<ProgramQueue> programQueues = programQueueDao.getAdmittedProgramQueuesByDemographicId(demographicNoAsLong); 
      if (programQueues != null && programQueues.size() > 0) { 
       for (ProgramQueue pq : programQueues) { 
        programIds.add(pq.getProgramId()); 
       } 

       List<ProgramProvider> programProviders = programProviderDAO.getProgramProviderByProviderProgramId(user_no, programIds); 

       if (programProviders != null && programProviders.size() > 0) { 
        canView = true; 
       } 
      } 
     } 

     String useNewCaseMgmt; 
     if((useNewCaseMgmt = request.getParameter("newCaseManagement")) != null) {  
      session.setAttribute("newCaseManagement", useNewCaseMgmt); 
      ArrayList<String> users = (ArrayList<String>)session.getServletContext().getAttribute("CaseMgmtUsers"); 
      if(users != null) { 
       users.add(request.getParameter("providerNo")); 
       session.getServletContext().setAttribute("CaseMgmtUsers", users); 
      } 
     } 
     else { 
      useNewCaseMgmt = (String)session.getAttribute("newCaseManagement");    
     } 

     String requestURI = httpRequest.getRequestURI(); 
     String contextPath = httpRequest.getContextPath(); 

     if (!canView && !requestURI.startsWith(contextPath + "/casemgmt/accessRequest.jsp")) { 
      httpResponse.sendRedirect(contextPath + "/casemgmt/accessRequest.jsp?" + httpRequest.getQueryString()); 
      return; 
     } 

     logger.debug("AccessRequestFilter chainning"); 
     chain.doFilter(new FilteredRequest(request), response); 
    } 
} 

过滤器是安装拦截所有请求,并进入一个名为casemgmt子目录前​​锋。在web.xml中的过滤器是这样的:

<filter> 
     <filter-name>AccessRequestFilter</filter-name> 
     <filter-class>org.oscarehr.casemgmt.filter.AccessRequestFilter</filter-class> 
    </filter> 
... 
<filter-mapping> 
     <filter-name>AccessRequestFilter</filter-name> 
     <url-pattern>/casemgmt/*</url-pattern> 
     <dispatcher>REQUEST</dispatcher> 
     <dispatcher>FORWARD</dispatcher> 
    </filter-mapping> 

任何人有任何想法如何,我可以真正去除“理由”参数?

+0

你究竟是什么意思时,你说“查询字符串”?你在浏览器的地址栏中看到的那个?顺便说一句,你的'getRequestURL()'覆盖是不必要的。它根本不包含查询字符串部分。 – BalusC 2013-02-15 01:42:23

+0

啊..好了,我越来越绝望了,所以我开始实施一些我可能不需要的方法。我澄清了我在帖子中查询字符串的含义。谢谢。 – Jarrett 2013-02-15 01:45:30

+0

嗯好的。你为什么认为包装和操纵HTTP servlet请求会影响浏览器地址栏中的URL?只有重定向才能做到这一点。 – BalusC 2013-02-15 01:47:17

回答

2

在服务器端环绕和操作HttpServletRequest绝对不会像浏览器的地址栏中看到的那样神奇地影响URL。该网址保持原样,因为它是浏览器用来请求所需资源的网址。包装的请求只会影响同一个请求上的筛选器后运行的服务器端代码。

如果您想要更改浏览器地址栏中的网址,则应该将重定向发送到所需的网址。

基本上,

if (reasonParameterIsIn(queryString)) { 
    response.sendRedirect(requestURL + "?" + removeReasonParameterFrom(queryString)); 
    return; 
} 
+0

但是,为什么在URL中显示为GET参数的原因参数(它在过滤器中被捕获之前以POST形式发送)? – Jarrett 2013-02-15 16:01:05

+0

显然它出现在'

' URL中,或者在另一个过滤器重定向时添加。 – BalusC 2013-02-15 16:29:22

+0

嗯......很奇怪。我看不到任何地方,但是有很多地方,所以这是可能的。无论如何,感谢您的帮助,我现在就可以做到我想要的。欢呼@BususC! – Jarrett 2013-02-15 17:15:24

相关问题