java.lang.IllegalStateException: 提交响应后无法调用sendRedirect()
描述:过滤器中重写的doFilter方法中:先是if(条件)中有 filterChain.doFilter(servletRequest, servletResponse); 代表条件满足时放行,将拦截的请求对象和响应对象提交给Tomcat服务器,if结束后还有一个if,其中又写了可能执行的filterChain.doFilter(servletRequest, servletResponse)的放行语句
public class OneFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//通过拦截的请求对象(先向下转型)向Tomcat索要当前用户的HttpSession
HttpServletRequest request = (HttpServletRequest) servletRequest;
//调用请求对象读取请求包中请求行中的URI(URL的一部分[/网站名/资源文件名]),看看用户想访问的资源文件是什么
String uri = request.getRequestURI();
//看URI中是否包含和login有关的东西,有则无条件放行,或者Tomcat设置的默认访问文件也无条件放行:例如某个新网站项目默认启动时打开index.html这样的情况
if (uri.indexOf("login") != -1 || "/myweb/".equals(uri)) {
filterChain.doFilter(servletRequest, servletResponse);
}
//如果本次用户访问的是其他资源文件
HttpSession session = null;
session = request.getSession(false);//判断会话令牌是否有,没有则返回空
if (session != null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
//拒绝资源请求,让其去访问另一个资源文件
request.getRequestDispatcher("/login_error.html").forward(servletRequest, servletResponse);
}
}
}
问题所在:如果第一个if满足了,执行了filterChain.doFilter(servletRequest, servletResponse)放行语句,请求和响应对象提交给Tomcat服务器,响应已经转发了,后面的如果条件再次满足执行filterChain.doFilter(servletRequest, servletResponse)放行语句,转发响应,则会报错说响应已提交,无法掉用
解决:将第一个if后面的全部用else包裹起来,让其响应只能提交一次
if (uri.indexOf("login") != -1 || "/myweb/".equals(uri)) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
//如果本次用户访问的是其他资源文件
HttpSession session = null;
session = request.getSession(false);//判断会话令牌是否有,没有则返回空
if (session != null) {
filterChain.doFilter(servletRequest, servletResponse);
} else {
//拒绝资源请求,让其去访问另一个资源文件
request.getRequestDispatcher("/login_error.html").forward(servletRequest, servletResponse);
}
}
java.lang.ClassCastException: class java.lang.String cannot be cast to class java.lang.Integerjava.lang
描述:从全局作用域对象中(存储类型类似Map,键值对)取共享数据时,然后再强转成需要的类型时报错:Integer userId = (Integer) application.getAttribute("userId");
问题所在:因为在放数据时:application.setAttribute("userId",userId);从请求中取出的参数userId是String类型,直接将String类型赋给键的值了,不管是Map的put,还是这里类似Map存储结构的全局作用域对象application的setAttribute,放的时候如果不是Integer类型,getAttribute取的时候强转成Integer类型就会报错
解决:放数据的时候将类型转换一下 application.setAttribute("userId",Integer.valueOf(userId));