关于Filter中的两个异常,重定向后要加Return

这是个很常见的问题,度娘和谷歌动手就能查到,可是今天还是遇到了,因为一直做业务研发,没有直接关注这些细节。

该文章来自ITeye,网络爬虫请自重!欢迎大家访问我的博客

这两个异常如下:

1、Java代码

java.lang.IllegalStateException: Cannot forward after response has been committed  
    at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:313)  
    at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)  
    at com.servlet.MyServlet2.doGet(MyServlet2.java:22)  
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)  
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)  
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)  
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)  
    at com.filter.MyFilter.doFilter(MyFilter.java:48)  
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)  
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)  
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)  
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)  
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)  
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)  
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)  
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:216)  
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)  
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:634)  
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)  
    at java.lang.Thread.run(Unknown Source)  

2、Java 代码

java.lang.IllegalStateException  
    at org.apache.catalina.connector.ResponseFacade.sendError(ResponseFacade.java:407)  
    at org.apache.catalina.servlets.DefaultServlet.serveResource(DefaultServlet.java:662)  
    at org.apache.catalina.servlets.DefaultServlet.doGet(DefaultServlet.java:325)  
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)  
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)  
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)  
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)  
    at com.filter.MyFilter.doFilter(MyFilter.java:48)  
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)  
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)  
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)  
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)  
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)  
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)  
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)  
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:216)  
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)  
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:634)  
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)  
    at java.lang.Thread.run(Unknown Source)  

只要在重定向后加return就可以了。

Java代码  

public void doFilter(ServletRequest request, ServletResponse response,  
        FilterChain chain) throws IOException, ServletException {  
    request.setCharacterEncoding("UTF-8");  
    response.setCharacterEncoding("UTF-8");       
    HttpServletRequest hrequest = (HttpServletRequest)request;  
    String path = hrequest.getContextPath();  
    String basePath = hrequest.getScheme()+"://"+hrequest.getServerName()+":"+hrequest.getServerPort()+path+"/";  
    // 获得请求的全路径  
    String reUrl = hrequest.getRequestURL().toString();  
    // 是否包含参数  
    int index = reUrl.indexOf("?");  
    String re = "";  
    if(index == -1){  
        re = reUrl.substring(basePath.length());  
    }else{  
        re = reUrl.substring(basePath.length(), index);  
    }  
    // 是否是请求资源  
    if(!isResource(re)){  
        // 是否有访问的权限  
        boolean isCheck = ConnUril.checkUrl(re);  
        if(!isCheck){  
            request.getRequestDispatcher("/error.jsp").forward(request,response);  
            // 必须加返回,否则报错  
            return ;  
        }  
    }  
    // 继续执行  
    chain.doFilter(request, response);  
}  

报错原因很简单,转向后再去执行关于response的操作,就等于执行了两遍转向,因此会报错!

问题简单,也需要留意,再简单的问题也是问题,成功在细节和那些别人以为是傻冒的问题中。

原文网址:http://cuisuqiang.iteye.com/blog/1478086

### 回答1: 可以先实现一个简单的Filter,用来校验用户的登录状态和权限,具体的实现步骤如下:1. 实现一个Filter类,实现Filter接口,覆盖doFilter方法,在方法实现用户登录校验和权限校验的逻辑。2. 配置web.xml文件,配置Filter和要校验的URL,同时配置Filter的初始参数,如登录页面URL等。3. 创建一个Filter实例,并将其配置到web.xml文件,完成Filter的配置。4. 启动服务器,Filter就会根据web.xml文件的配置,实现用户登录校验和权限校验的功能。 ### 回答2: 用户登录校验和权限校验是Web应用开发非常常见的功能之一。在Java Web应用,可以使用原生Java编写Filter来实现这个功能。 FilterJava Servlet规范提供的一种组件,可以对请求进行拦截和处理。下面是一个用原生Java编写的登录校验和权限校验的Filter的示例: 首先,需要创建一个类来实现Filter接口,并重写其doFilter方法,该方法将在每一个请求被执行时被调用。在doFilter方法,我们可以对请求进行相关的校验和处理。 ```java public class AuthenticationFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest httpRequest = (HttpServletRequest) request; HttpServletResponse httpResponse = (HttpServletResponse) response; // 进行用户登录校验 boolean isLoggedIn = checkUserLoggedIn(httpRequest); if (!isLoggedIn) { httpResponse.sendRedirect("/login"); // 未登录则跳转到登录页面 return; } // 进行权限校验 boolean hasPermission = checkUserPermission(httpRequest); if (!hasPermission) { httpResponse.sendError(HttpServletResponse.SC_FORBIDDEN, "Access Denied"); // 没有权限则返回403错误 return; } chain.doFilter(request, response); // 放行请求 } // 校验用户是否已登录 private boolean checkUserLoggedIn(HttpServletRequest request) { // 实现具体的登录校验逻辑,比如判断Session是否存在登录信息 // 返回一个boolean值表示是否已登录 } // 校验用户是否有权限访问资源 private boolean checkUserPermission(HttpServletRequest request) { // 实现具体的权限校验逻辑,比如判断用户角色是否具备访问权限 // 返回一个boolean值表示是否有权限 } } ``` 然后,在web.xml文件配置该Filter,指定需要被该Filter拦截的URL模式: ```xml <filter> <filter-name>AuthenticationFilter</filter-name> <filter-class>com.example.AuthenticationFilter</filter-class> </filter> <filter-mapping> <filter-name>AuthenticationFilter</filter-name> <url-pattern>/*</url-pattern> // 拦截所有URL </filter-mapping> ``` 以上代码是一个简单的示例,实际应用可能需要根据具体需求进行一些调整和优化。这个Filter可以在用户每次请求时拦截并进行用户登录校验和权限校验,从而实现这两个功能的自动化处理。 ### 回答3: 要用原生Java写一个Filter实现用户登录校验和权限校验,可以按照以下步骤进行实现: 1. 创建一个Java类,命名为LoginFilter,实现javax.servlet.Filter接口。 2. 在LoginFilter,实现doFilter方法,该方法接收三个参数:ServletRequest request, ServletResponse response, FilterChain chain。此方法会在每次请求前后被调用。 3. 在doFilter方法,首先获取用户的登录信息,可以通过从request对象获取session或者cookie等方式来获取。 4. 如果用户没有登录信息,则将请求重定向到登录页面,或者返回相应的错误提示,用于告知用户需要先登录才能访问页面。 5. 如果用户已经登录,则进一步校验用户的权限。可以通过获取用户的角色或者拥有的权限列表来进行校验。 6. 如果用户没有足够的权限,则同样将请求重定向到相应的错误页面,或者返回相应的错误提示。 7. 如果用户通过了登录和权限的校验,可以通过调用chain.doFilter(request, response)方法,继续执行其他Filter或者Servlet。 8. 最后,需要将LoginFilter类配置在web.xml文件,以便让容器在每个请求过程都能调用该过滤器。 通过以上步骤,我们就可以通过原生Java写一个Filter来实现用户登录校验和权限校验。当用户请求一个需要登录和权限的页面时,该Filter会进行相应的校验,并根据校验结果决定是否允许用户访问页面。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值