A. java日志的filter
Filter可以视作是servlet的加强版,主要用作对用户的请求进行预处理,或者对返回给客户端的结果进行再次加工,是一个典型的链式处理模式。本篇简单介绍filter的基本使用方法,主要涉及以下内容:
Filter的背景知识
使用Filter的流程
Filter的生命周期
一个完整的实例
一、Filter的简单介绍
Filter在英文中是过滤器的意思,当然在此处的使用也是完美的切合了它的意思,我们使用filter的主要目的就是完成一个过滤的作用。可以在一个请求到达servlet之前,将其截取进行逻辑判断,然后决定是否放行到请求的servlet。也可以在一个response到达客户端之前,截取结果进行逻辑判断,然后决定是否允许返回给客户端。所以filter有如下几个种类:
用户授权的filter:filter负责判断用户是否有权限请求该页面,给予过滤判断
日志filter:截取某个用户在本网站上的所有请求,记录轨迹
负责解码的filter:规定处理本次请求的解码方式
最后需要注意的是,一个filter过滤器可以加在多个servlet控制器上,当然多个filter过滤器也是可以加在一个servlet控制器上的。由此也是可以看出来,我们使用filter往往是对一些公共的操作进行处理,例如:判断用户权限,解码本次请求等,还比如,我们的web应用中某些页面是需要用户登录后才能访问的,以往我们都是在每个servlet页面加上判断控制,导致代码冗余,有了filter,我们可以定义一个实现了filter的过滤器,让需要判断是否登录的页面都加上这么一个过滤器,可以大大降低代码的冗余程度。
二、Filter的使用流程
在Java中如果想要自定义一个filter过滤器的话,需要继承Javax.servlet.Filter接口,这个接口中只有三个方法:
其中init和destroy方法是有默认实现的,也就是我们不是必须重写这两个方法,但是doFilter 这个方法是一个核心的方法,是我们必须要实现的。首先我们看init方法的作用,这个方法是用来初始化filter实例的,也就是当用户请求了某个拦截器而此拦截器又匹配了某个过滤器,此时web容器就会定位到该过滤器然后创建该filter类的实例对象并调用此实例的init方法,完成初始化工作。对于destroy方法毋庸置疑就是在过滤器执行结束的时候调用,主要完成对一些资源的释放。下面主要看dofilter这个方法。
doFilter方法是filter接口中的核心方法,一旦创建完该过滤器的实例之后,会执行dofilter方法,所有的过滤逻辑都是在此方法中进行的。主要有三个参数,第一个参数是一个ServletRequest对象,HttpServletRequest继承于此接口,当用户请求某个拦截器的时候,检测到此请求存在过滤器,于是会封装好本次请求的相关数据,传递给dofilter的ServletRequest参数,ServletResponse参数的来源和ServletRequest是一样的,都是由客户端封装过来的。至于第三个参数,这是一个FilterChain处理链,详细的介绍等说明了web.xml中配置filter之后。
第一步如上,创建一个继承自filter接口的类,并实现其中的三个方法。第二步是在web.xml中配置该类用于过滤哪些拦截器。web.xml代码如下:
如上述的代码,我们需要两个操作,首先是定义一个filter,指定了该filter的name和相对应的过滤器类。然后我们可以通过filter-mapping映射过滤器和URL,此处使用了两个映射,对该过滤器指定了对路径名为/a和/b的请求进行拦截。当然这个url-pattern元素的值可以有以下三种形式,完全匹配(/a/b等),目录匹配(/* 、 /abc/等),扩展名(.a,*.b等)。
了解了配置filter的主要操作之后,我们回去看过滤器类,我们说init方法是在首次创建filter实例的时候,用于执行初始化操作的,其中有个参数FilterConfig ,这是当前filter的配置信息,其中方法如下:
其实在创建filter实例的时候,web容器会将此实例对应在web.xml中的配置信息读取并封装成一个FilterConfig 对象传递给init方法,getFilterName方法就是我们在web.xml中配置的filter-name,getServletContext会获取当前servlet的上下文,当我们在定义filter的时候使用<init-param>来定义一些初始化参数的时候,就可以使用此方法来获取这些初始化参数。getInitParameterNames方法用于获取所有初始化参数的枚举集合。这样我们在init方法中就可以获取这些配置参数,初始化filter实例。
上面我们只定义了一个filter,如果我们对于一次请求需要执行多个filter,进行过滤操作的话,web容器会在你请求某个URL的时候,在web.xml中找到所有匹配的filter,按照注册的顺序以FilterChain 链的形式传递到方法doFilter的第三个参数中,而这个filterChain中只有一个方法:
如果我们在 void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) 方法中调用var3.doFilter(var1,var2),就代表此filter实例结束,则web服务器会检查FilterChain对象中是否还有filter对象(因为这是一个链,filter的数量是大于等于一的),如果没有就会放行,直接调用目标地址,如果还有filter对象,就会转而执行下一个filter。正是由于这样的机制,我们才可以对于一个URL请求添加多个filter过滤器。
三、一个简单的实例
下面通过一个简单的实例直观的感受下filter过滤器的作用:
我们首先访问set.jsp页面设置本次会话的session值,然后修改浏览器地址栏访问index.jsp页面
上述的demo只是为了简单的演示,其实使用filter可以完成大大的降低我们的代码的冗余程度。这个例子是为了演示,所以很简单。
四、Filter 的生命周期
当用户请求某个页面时候,会到web.xml中匹配是否存在能够匹配上此次请求的filter,如果有封装它的配置信息,FilterChain链。然后调用init方法,完成初始化,接着调用dofilter方法,处理核心逻辑,当此实例被销毁的时候,会调用destroy方法。
B. JAVA的web.xml配置filter,想让不包含 /aaa/ 的路径进入方法,该怎么配置url-partten
用 <url-pattern></url-pattern> 不行,可以自己在 Filter 里用正则表达式进行二次过滤,过滤的回正则表达式可以通过:答
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.test.LoginFilter</filter-class>
<init-param>
<param-name>UrlRegx</param-name>
<param-value><!--你的正则表达式--></param-value>
</init-param>
</filter>
配置,然后在 Filter 里通过 getInitParameter() 读取。
C. Java Web 怎样修改request的参数值
用过滤器就可以实现,现在web.xml文件中配置好过滤器,自定义个一个过滤器,实现Filter接口,在doFilter中实现自己的过滤逻辑,我这里有个设置所有请求中的字符编码,你可以参考一下:
Java code
web.xml配置如下:
<filter>
<!--过滤器名称,随便定义-->
<filter-name>UrlFilter</filter-name>
<!--filter-class指向自定义的过滤器,完整的包名+类名-->
<filter-class>
com.wgh.common.SetCharacterEncodingFilter
</filter-class>
<!--过滤器中的默认参数,默认的字符编码是GBK-->
<init-param>
<param-name>defaultEncoding</param-name>
<param-value>GBK</param-value>
</init-param>
</filter>
<!--filter和filter-mapping是成对出现的-->
<filter-mapping>
<!--过滤器名称,一定要和上面的一样,-->
<filter-name>UrlFilter</filter-name>
<!--表示拦截所有的请求-->
<url-pattern>/*</url-pattern>
</filter-mapping>
SetCharacterEncodingFilter过滤器类:
packagecom.wgh.common;
importjava.io.IOException;
importjava.text.SimpleDateFormat;
importjava.util.Arrays;
importjava.util.Enumeration;
importjava.util.List;
importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
{privatestaticStringlog="ksURL_log";
privatestaticStringweb_xml_url;
=null;
=null;
protectedbooleanignore=true;
publicvoiddestroy(){
this.defaultEncoding=null;
this.filterConfig=null;
this.web_xml_url=null;
}
publicvoiddoFilter(ServletRequestrequest,ServletResponseresponse,
FilterChainchain)throwsIOException,ServletException{
if(ignore||(request.getCharacterEncoding()==null)){
StringdefaultEncoding=selectEncoding(request);
HttpServletRequestreq=(HttpServletRequest)request;
if(defaultEncoding!=null){
Stringuri=req.getRequestURI();
Stringurl_suffix=uri.substring(uri.lastIndexOf("/")+1);
request.setCharacterEncoding(defaultEncoding);
}
}
}
publicvoidinit(FilterConfigfilterConfig)throwsServletException{
this.filterConfig=filterConfig;
this.defaultEncoding=filterConfig.getInitParameter("defaultEncoding");
Stringvalue=filterConfig.getInitParameter("ignore");
if(value==null)
this.ignore=true;
elseif(value.equalsIgnoreCase("true"))
this.ignore=true;
elseif(value.equalsIgnoreCase("yes"))
this.ignore=true;
else
this.ignore=false;
}
protectedStringselectEncoding(ServletRequestrequest){
return(this.defaultEncoding);
}
}
D. java项目和web项目中的过滤器文件怎么使用
过滤器是一个程序,它先于与之相关的servlet或JSP页面运行在服务器上。过滤器可附加到一个或多个servlet或JSP页面上,并且可以检查进入这些资源的请求信息。在这之后,过滤器可以作如下的选择:
1. 以常规的方式调用资源(即,调用servlet或JSP页面)。
2.利用修改过的请求信息调用资源。
3. 调用资源,但在发送响应到客户机前对其进行修改
4. 阻止该资源调用,代之以转到其他的资源,返回一个特定的状态代码或生成替换输出。
1. 建立基本过滤器
建立一个过滤器涉及下列五个步骤:
1)建立一个实现Filter接口的类。这个类需要三个方法,分别是:doFilter、init和destroy。
doFilter方法包含主要的过滤代码(见第2步),init方法建立设置操作,而destroy方法进行清楚。
2)在doFilter方法中放入过滤行为。doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息(包括表单数据、cookie和HTTP请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过滤器中忽略此参数。最后一个参数为FilterChain,如下一步所述,此参数用来调用servlet或JSP页。
3)调用FilterChain对象的doFilter方法。Filter接口的doFilter方法取一个FilterChain对象作为它的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。
4)对相应的servlet和JSP页面注册过滤器。在部署描述符文件(web.xml)中使用filter和filter-mapping元素。
5)禁用激活器servlet。防止用户利用缺省servlet URL绕过过滤器设置。
1.1 建立一个实现Filter接口的类
所有过滤器都必须实现javax.servlet.Filter。这个接口包含三个方法,分别为doFilter、init和destroy。
public void doFilter(ServletRequset request,
ServletResponse response,
FilterChain chain)
thows ServletException, IOException
每当调用一个过滤器(即,每次请求与此过滤器相关的servlet或JSP页面)时,就执行其doFilter方法。正是这个方法包含了大部分过滤逻辑。第一个参数为与传入请求有关的ServletRequest。对于简单的过滤器,大多数过滤逻辑是基于这个对象的。如果处理HTTP请求,并且需要访问诸如getHeader或getCookies等在ServletRequest中无法得到的方法,就要把此对象构造成HttpServletRequest。
第二个参数为ServletResponse。除了在两个情形下要使用它以外,通常忽略这个参数。首先,如果希望完全阻塞对相关servlet或JSP页面的访问。可调用response.getWriter并直接发送一个响应到客户机。其次,如果希望修改相关的servlet或JSP页面的输出,可把响应包含在一个收集所有发送到它的输出的对象中。然后,在调用serlvet或JSP页面后,过滤器可检查输出,如果合适就修改它,之后发送到客户机。
DoFilter的最后一个参数为FilterChain对象。对此对象调用doFilter以激活与servlet或JSP页面相关的下一个过滤器。如果没有另一个相关的过滤器,则对doFilter的调用激活servlet或JSP本身。
public void init(FilterConfig config) thows ServletException
init方法只在此过滤器第一次初始化时执行,不是每次调用过滤器都执行它。对于简单的过滤器,可提供此方法的一个空体,但有两个原因需要使用init。首先,FilterConfig对象提供对servlet环境及web.xml文件中指派的过滤器名的访问。因此,普遍的办法是利用init将FilterConfig对象存放在一个字段中,以便doFilter方法能够访问servlet环境或过滤器名.其次,FilterConfig对象具有一个getInitParameter方法,它能够访问部署描述符文件(web.xml)中分配的过滤器初始化参数。
public void destroy( )
大多数过滤器简单地为此方法提供一个空体,不过,可利用它来完成诸如关闭过滤器使用的文件或数据库连接池等清除任务。
1.2 将过滤行为放入doFilter方法
doFilter方法为大多数过滤器地关键部分。每当调用一个过滤器时,都要执行doFilter。对于大多数过滤器来说,doFilter执行的步骤是基于传入的信息的。因此,可能要利用作为doFilter的第一个参数提供的ServletRequest。这个对象常常构造为HttpServletRequest类型,以提供对该类的更特殊方法的访问。
1.3 调用FilterChain对象的doFilter方法
Filter接口的doFilter方法以一个FilterChain对象作为它的第三个参数。在调用该对象的doFilter方法时,激活下一个相关的过滤器。这个过程一般持续到链中最后一个过滤器为止。在最后一个过滤器调用其FilterChain对象的doFilter方法时,激活servlet或页面自身。
但是,链中的任意过滤器都可以通过不调用其FilterChain的doFilter方法中断这个过程。在这样的情况下,不再调用JSP页面的serlvet,并且中断此调用过程的过滤器负责将输出提供给客户机。
1.4 对适当的servlet和JSP页面注册过滤器
部署描述符文件的2.3版本引入了两个用于过滤器的元素,分别是:filter和filter-mapping。filter元素向系统注册一个过滤对象,filter-mapping元素指定该过滤对象所应用的URL。
下面是一个完整的例子:
//建立一个实现Filter接口的类。这个类需要三个方法,分别是:doFilter、init和destroy。
//doFilter方法包含主要的过滤代码,init方法建立设置操作,而destroy方法进行清
package filterpkg;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
public class testFilter implements Filter{
public void init(FilterConfig filterConfig) throws ServletException
{
}
//在doFilter方法中放入过滤行为。doFilter方法的第一个参数为ServletRequest对象。
//此对象给过滤器提供了对进入的信息(包括表单数据、cookie和HTTP请求头)的完全访问。
//第二个参数为ServletResponse,通常在简单的过滤器中忽略此参数。
//最后一个参数为FilterChain,如下一步所述,此参数用来调用servlet或JSP页。
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain filterChain)
{
PrintWriter wout=null;
try
{
wout=response.getWriter();
}
catch(IOException e)
{
}
HttpServletRequest req=(HttpServletRequest)request;//将request转化为它的子类HttpServletRequest
String uri=req.getRequestURI();//获得传入的URI
if (uri.indexOf("MyJsp.jsp")>0 ||uri.indexOf("MainForm.do")>0 )//如果是我们指定的登录页面或验证页面
{
try
{
//调用FilterChain对象的doFilter方法。Filter接口的doFilter方法取一个FilterChain对象作为它的一个参数。
//在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。
filterChain.doFilter(request, response);
}
catch(Exception e)
{
}
return;
}
if (req.getSession()!=null)
if (req.getSession().getAttribute("USERID")==null)
{
wout.write("<HTML><BODY> Check error! <br/> </BODY> </HTML>");
wout.flush();
return;
}
try
{
filterChain.doFilter(request, response);
}
catch(Exception e)
{
}
}
public void destroy()
{
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<filter>
<filter-name>CHECKCODE</filter-name>
<filter-class>filterpkg.testFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CHECKCODE</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>ControlServlet</servlet-name>
<servlet-class>filterpkg.ControlServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ControlServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
E. filter的使用 java 过滤器的几种使用方法
过滤来器
过滤器是处于客户端与服务自器资源文件之间的一道过滤网,在访问资源文件之前,通过一系列的过滤器对请求进行修改、判断等,把不符合规则的请求在中途拦截或修改。也可以对响应进行过滤,拦截或修改响应。
过滤器一般用于登录权限验证、资源访问权限控制、敏感词汇过滤、字符编码转换等等操作,便于代码重用,不必每个servlet中还要进行相应的操作。
F. javaweb怎么对url进行过滤
在web.xml里面配置,如下:
<filter>
<filter-name>FileUploadFilter</filter-name>
<filter-class>com.ckfinder.connector.FileUploadFilter</filter-class>
<init-param>
<param-name>sessionCookieName</param-name>
<param-value>jsessionid</param-value>
</init-param>
<init-param>
<param-name>sessionParameterName</param-name>
<param-value>JSESSIONID</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FileUploadFilter</filter-name>
<url-pattern>/plug-in/ckfinder/core/connector/java/connector.java</url-pattern>
</filter-mapping>
有一个 和一个filter-mapping>
G. javaee 过滤器怎样判断输入的url路径是正确的,不正确则跳转index.jsp
JSP 图片无瞎手液法显示通常是由于以下原因:
1、文件路径或文件名称的问题,这需要验证文件的路径是否正确是否区分了大小写。jsp路径也是十分特殊的,相对路径有时候是无效的,所以需要使用绝对路径,路径前使用<%=request.getContextPath() %>.
2、图片的规格有问题,验证的方式是:在文件管理器中鼠标右键图片,选择打开方式IE,看是否能打开,能正常打开的图片就没薯老有问题。
3、显示图片的代码写的不对。这里只能看到提问,看不到详细,猜测可能会有这样的错误,或者是调用标签方式不正确,html有两种调用图片的方式,一种是图片标签直接做展示,另一种则是通过背景的形式展现,如下:
<img src="imagePath" />
<xxx style="background:url(imagePath);"></xxx>
<xxx style="background-image:imagePath;"></xxx>
4、被覆盖。如果图片因为被别的div或者其他html控件盖住了,就不会显示正常了,磨物可以通过IE浏览器点“F12”打开开发人员工具,在“HTML”选项卡下有个光标的图标,点击后再点击页面中药显示图片的区域,开发人员工具的面板中的代码块就自动跳到该区域对应的代码并且高亮显示,这样就可以知道是什么将图片覆盖在后面了。出现此种情况需要先看是否两个区域都正确,如果该覆盖图片的区块是被挤到这里来的,则需要重新调整此区块的位置,若是确实应该是和图片重叠显示的,则需要在图片中添加样式:z-index,数值比那个区块大即可。
H. java过滤器不过滤某个货某一些路径
首先在web.xml 配置 参数
<param-name>noLoginPaths</param-name> 参数名可自取
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.imooc.filter.LoginFilter</filter-class>
<init-param>
<param-name>noLoginPaths</param-name>
<param-value>login.jsp;fail.jsp;LoginServlet</param-value>
</init-param>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
然后在 Filter 中,创建一个FilterConfig 的引用, 这个引用在init中初始化,并且能够通过它获取<init-param>中的key和value ,
StringnoLoginPaths=config.getInitParameter("noLoginPaths");
然后通过判断用户请求的url 是否符合 noLoginPaths 中设置的不过滤选项,如果如何,就调用do.filter放行
关键代码 :
if(noLoginPaths!=null){
String[]strArray=noLoginPaths.split(";");
for(inti=0;i<strArray.length;i++){
if(strArray[i]==null||"".equals(strArray[i]))continue;
if(request.getRequestURI().indexOf(strArray[i])!=-1){
arg2.doFilter(arg0,arg1);
return;
}
}
}
完整代码:
importjava.io.IOException;
importjavax.servlet.Filter;
importjavax.servlet.FilterChain;
importjavax.servlet.FilterConfig;
importjavax.servlet.ServletException;
importjavax.servlet.ServletRequest;
importjavax.servlet.ServletResponse;
importjavax.servlet.http.HttpServletRequest;
importjavax.servlet.http.HttpServletResponse;
importjavax.servlet.http.HttpSession;
{
privateFilterConfigconfig;
@Override
publicvoiddestroy(){
}
@Override
publicvoiddoFilter(ServletRequestarg0,ServletResponsearg1,FilterChainarg2)throwsIOException,ServletException{
HttpServletRequestrequest=(HttpServletRequest)arg0;
HttpServletResponseresponse=(HttpServletResponse)arg1;
HttpSessionsession=request.getSession();
StringnoLoginPaths=config.getInitParameter("noLoginPaths");
Stringcharset=config.getInitParameter("charset");
if(charset==null){
charset="UTF-8";
}
request.setCharacterEncoding(charset);
if(noLoginPaths!=null){
String[]strArray=noLoginPaths.split(";");
for(inti=0;i<strArray.length;i++){
if(strArray[i]==null||"".equals(strArray[i]))continue;
if(request.getRequestURI().indexOf(strArray[i])!=-1){
arg2.doFilter(arg0,arg1);
return;
}
}
}
if(session.getAttribute("username")!=null){
arg2.doFilter(arg0,arg1);
}else{
response.sendRedirect("login.jsp");
}
}
@Override
publicvoidinit(FilterConfigarg0)throwsServletException{
config=arg0;
}
}