Filter 简介
在 Java 程序当中我们可以设置 filter 过滤器,filter 过滤器是 Servlet 技术中最实用的技术,Web 开发人员通过 Filter 技术,对 web 服务器管理的所有 web 资源:例如 Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现 URL 级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
Filter 功能
在HttpServletRequest
到达 Servlet 之前,拦截客户的HttpServletRequest
。根据需要检查HttpServletRequest
,也可以修改 HttpServletRequest 头和数据。
在HttpServletResponse
到达客户端之前,拦截HttpServletResponse
。根据需要检查HttpServletResponse
,也可以修改 HttpServletResponse 头和数据。
Filter 接口中有一个 doFilter 方法,我们可以使用这个方法去拦截 web 资源,Web 服务器每次在调用 web 资源的 service 方法之前,都会先调用一下 filter 的 doFilter 方法。
问题
但是当我使用 filter 拦截/*的 url 时,jsp 文件文件是使用 link 外部导入 css 文件的方式去设置页面的格式。但是当我运行程序之后并没有出现 CSS 写好的样式。出现Resource interpreted as Stylesheet but transferred with MIME type text/html
我的代码:
@WebFilter("/manage/*")
public class AdminLogin implements Filter {
/**
* Default constructor.
*/
public AdminLogin() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html;charset=utf-8");
HttpSession session = req.getSession();
String flag = (String)session.getAttribute("isAdminLogin");
String request_uri = req.getRequestURI();
String ctxPath= req.getContextPath();
String uri= request_uri.substring(ctxPath.length());
// System.out.println(request_uri+"##"+ctxPath+"##"+uri+"##"+flag);
if(uri.contains("admin_")){
if(flag !=null && flag.equals("1")) {
chain.doFilter(req, resp);
}else{
PrintWriter out = resp.getWriter();
out.write("<script>");
out.write("alert('请先登录!');");
out.write("location.href='login.jsp';");
out.write("</script>");
out.close();
return;
}
}else{
chain.doFilter(req, resp);
}
return;
//不通过则直接return
// pass the request along the filter chain
// chain.doFilter(req, resp); // 通过则使用这条语句
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
复制代码
问题解决
我去查看了控制台(F12),在网络中明明已经出现了需要的 common.css 和 main.css 文件,但是页面却没有使用。并且下面出现了Resource interpreted as Stylesheet but transferred with MIME type text/html:
代码警告。
我在查看请求到的 CSS 文件的请求头时发现这些 CSS 文件返回的类型都是 text/html 类型
这是我在网上查找方法时参考的博客:
原因:
我出现的问题应该是 filter 进行拦截时将 js,css,jpg 等外部导入的静态文件也进行了拦截,并且在 filter 中使用/*拦截,而且使用了 response.setContentType("text/html;charset=utf-8")去将文件类型度修改成了 text/html 的原因。
所以我修改过的代码如下:
@WebFilter("/manage/*")
public class AdminLogin implements Filter {
/**
* Default constructor.
*/
public AdminLogin() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest)request;
HttpServletResponse resp = (HttpServletResponse)response;
req.setCharacterEncoding("UTF-8");
/*这里设置response的类型我删除了*/
/*resp.setContentType("text/html;charset=utf-8");*/
resp.setCharacterEncoding("utf-8");
HttpSession session = req.getSession();
String flag = (String)session.getAttribute("isAdminLogin");
String request_uri = req.getRequestURI();
String ctxPath= req.getContextPath();
String uri= request_uri.substring(ctxPath.length());
// System.out.println(request_uri+"##"+ctxPath+"##"+uri+"##"+flag);
/*这里我增加了url判断,对静态文件直接放行*/
if(request_uri.toString().contains(".css") || request_uri.toString().contains(".js") || request_uri.toString().contains(".png")|| request_uri.toString().contains(".do")){
//如果发现是css或者js文件,直接放行
chain.doFilter(req, resp);
}else {
if(uri.contains("admin_")){
if(flag !=null && flag.equals("1")) {
chain.doFilter(req, resp);
}else{
PrintWriter out = resp.getWriter();
out.write("<script>");
out.write("alert('请先登录!');");
out.write("location.href='login.jsp';");
out.write("</script>");
out.close();
return;
}
}else{
chain.doFilter(req, resp);
}
}
return;
//不通过则直接return
// pass the request along the filter chain
// chain.doFilter(req, resp); // 通过则使用这条语句
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
复制代码
现在出现了我需要的结果:
评论