1.創建一個過濾器
我們首先創建一個web工程,
工程首頁有一個連接
<a href="<%=path %>/servlet/loginServlet?username=管理員&password=1">進入後臺</a>
這裏,我們創建一個servlet(關於如何創建和訪問servlet不是我們今天的重點)
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
}
這裏我們發現username會是亂碼,因此我們需要手動爲其設置編碼
req.setCharacterEncoding("GBK");
這個沒有問題,但是假設有N個servlet或則說有許多不同邏輯的請求,自然就需要很多的同樣操作
因此就需要一個字符的過濾器
OK
要實現過濾器,必須實現javax.servlet.Filter接口
並重寫doFilter方法
先貼代碼 在解釋
/**
* 字符過濾器
*
*/
// 實現過濾器的方法 實現filter接口 重寫doFilter方法
public class EncodeFilter implements Filter {
private String encode = null;
private boolean ignore = false;// 過濾器開關
public void destroy() {
encode = null;
ignore = false;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
if (!ignore) {
if (null == request.getCharacterEncoding()) {
request.setCharacterEncoding(encode);
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
String encode = filterConfig.getInitParameter("encode");
String ignore = filterConfig.getInitParameter("ignore");
if (this.encode == null)
this.encode = encode;
if ("1".equals(ignore) || "yes".equals(ignore)) {
this.ignore = true;
}
}
}
<filter>
<filter-name>encodeFilter</filter-name>
<filter-class>com.lwx.filter.EncodeFilter</filter-class>
<init-param>
<param-name>encode</param-name>
<param-value>GBK</param-value>
</init-param>
<init-param>
<param-name>ignore</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
這裏解釋下
<filter-mapping>中的<url-pattern>就是過濾器要過濾的對象/* 就是對所有的請求進行過濾
當然這裏還有一個過濾器的開關ignore 當ignore爲true/1/yes的時候,則過濾器不起作用,還有一個就是過濾器要設置的編碼格式的值
java代碼中,
init方法是初始化過濾器的時候調用一次
destroy 則不用解釋了
doFilter 則是需要我們去重寫的
OK 到此一個完整的字符過濾器就算結束,但是我們的話題還沒有結束
現在我有一個想法,那就是對非法用戶(沒有登錄的用戶和沒有權限訪問的用戶)進行過濾
二、登錄過濾器
我們知道,很多時候我們在影響用戶請求的時候,都需要判斷用戶是否已經登錄,或則他的session是否已經失效,如果是的話,則跳到登錄頁,等待重新登錄後纔可以繼續下一步的操作
OK
假設現在我們有一個登錄的頁面
代碼如下
1 <form action="<%=path %>/servlet/loginServlet?task=login" method="post">
2 <div>用戶名:<input type="text" name="username"></div>
3 <div>密碼:<input type="password" name="password"></div>
4 <div><input type="submit" value="登錄"></div>
5 </form>
if (task.equals("login")) {
if (null != username && username.trim().length() > 0
&& username.equals("lwx")) {
if (null != password && password.trim().length() > 0
&& password.equals("1")) {
User user = new User();
user.setUsername(username);
req.getSession().setAttribute("user", user);
resp.sendRedirect(req.getContextPath() + "/manager/");
}
}
}
後臺的處理代碼
當用戶名等於lwx並且密碼爲1的時候,我們將跳轉到/manager/index.jsp
假設現在用戶知道了這個地址,就可以輕鬆的訪問我們的頁面了,因此在進去之前需要做過濾
同時/servlet/loginServlet?task=login 這個請求又是不需要過濾的
因此綜上考慮 ,我們這樣設計過濾器
代 碼
public class LoginFilter implements Filter{
String permitUrls[]=null;
boolean ignore=false;
String gotoUrl=null;
public void destroy() {
permitUrls=null;
ignore=false;
gotoUrl=null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest res=(HttpServletRequest) request;
HttpServletResponse resp=(HttpServletResponse)response;
System.out.println("登錄過濾器");
if(!ignore){
if(!isPermitUrl(request)){
if(filterCurrUrl(request)){
resp.sendRedirect(res.getContextPath()+gotoUrl);
return ;
}
}
}
chain.doFilter(request, response);
}
public boolean isPermitUrl(ServletRequest request){
boolean isPermit=false;
if(permitUrls!=null&&permitUrls.length>0){
for (int i = 0; i < permitUrls.length; i++) {
if(permitUrls[i].equals(currentUrl(request))){
isPermit=true;
break;
}
}
}
return isPermit;
}
public boolean filterCurrUrl(ServletRequest request){
boolean filter=false;
HttpServletRequest res=(HttpServletRequest) request;
User user =(User) res.getSession().getAttribute("user");
if(null==user)
filter=true;
return filter;
}
//xx.jsp
// servlet/aaServlet?task=11&bb=yy
public String currentUrl(ServletRequest request){
HttpServletRequest res=(HttpServletRequest) request;
String task=request.getParameter("task");
String path=res.getContextPath();
String uri=res.getRequestURI();
if(task!=null){//uri格式 xx/ser
uri=uri.substring(path.length(), uri.length())+"?"+"task="+task;
}else{
uri=uri.substring(path.length(), uri.length());
}
System.out.println("當前請求地址:"+uri);
return uri;
}
public void init(FilterConfig filterConfig) throws ServletException {
String ignore =filterConfig.getInitParameter("ignore");
String permitUrls =filterConfig.getInitParameter("permitUrls");
String gotoUrl =filterConfig.getInitParameter("gotoUrl");
if ("1".equals(ignore) || "yes".equals(ignore)||"true".equals(ignore)) {
this.ignore = true;
}
if(permitUrls!=null&&permitUrls.length()>0);
this.permitUrls=permitUrls.split(",");
this.gotoUrl=gotoUrl;
}
}
代 碼
代 碼
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.lwx.filter.LoginFilter</filter-class>
<init-param>
<param-name>ignore</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>permitUrls</param-name>
<param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp</param-value>
</init-param>
<init-param>
<param-name>gotoUrl</param-name>
<param-value>/login/login.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
public class User {
private String username;
private String password;
}
OK,登錄過濾器仍然全部的請求地址,
permitUrls 用來告訴過濾器哪些請求是登錄過濾器不需要過濾的,最簡單的肯定是首頁,和登錄校驗的地址
gotoUrl 表示當過濾器接收到非法請求的時候,需要跳轉的頁面 這樣的好處是假設下次需要修改跳轉的頁面 只要修改配置文件,而不需要重新編譯代碼
三、權限過濾器
感覺到這裏,視乎是可以告一個段落了,其實不然。
假設我們有一個一般的用戶,他登錄後請求的一個地址是管理員纔可以訪問的 那對於網站來說是非常不利的。因此權限的過濾器也是非常有必要的
還是先上代碼
public class AuthorityFilter implements Filter{
String permitUrls[]=null;
boolean ignore=false;
String gotoUrl=null;
public void destroy() {
permitUrls=null;
ignore=false;
gotoUrl=null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest res=(HttpServletRequest) request;
HttpServletResponse resp=(HttpServletResponse)response;
System.out.println("權限過濾器");
if(!ignore){
if(!isPermitUrl(request)){
if(filterCurrUrl(request)){
resp.sendRedirect(res.getContextPath()+gotoUrl);
return ;
}
}
}
chain.doFilter(request, response);
}
public boolean isPermitUrl(ServletRequest request){
boolean isPermit=false;
if(permitUrls!=null&&permitUrls.length>0){
for (int i = 0; i < permitUrls.length; i++) {
if(permitUrls[i].equals(currentUrl(request))){
isPermit=true;
break;
}
}
}
return isPermit;
}
public boolean filterCurrUrl(ServletRequest request){
boolean filter=true;
HttpServletRequest res=(HttpServletRequest) request;
User user =(User) res.getSession().getAttribute("user");
//List authorities=user.getUserAuthorities();
//遍歷authorities判斷是否是該用戶擁有的權限 否則
//這裏我們假定用戶用戶訪問/manager/user_list.jsp的權限
String currentUrl=currentUrl( request);
if("/servlet/loginServlet?task=userlist".equals(currentUrl))
filter=false;
return filter;
}
//xx.jsp
// servlet/aaServlet?task=11&bb=yy
public String currentUrl(ServletRequest request){
HttpServletRequest res=(HttpServletRequest) request;
String task=request.getParameter("task");
String path=res.getContextPath();
String uri=res.getRequestURI();
if(task!=null){//uri格式 xx/ser
uri=uri.substring(path.length(), uri.length())+"?"+"task="+task;
}else{
uri=uri.substring(path.length(), uri.length());
}
System.out.println("當前請求地址:"+uri);
return uri;
}
public void init(FilterConfig filterConfig) throws ServletException {
String ignore =filterConfig.getInitParameter("ignore");
String permitUrls =filterConfig.getInitParameter("permitUrls");
String gotoUrl =filterConfig.getInitParameter("gotoUrl");
if ("1".equals(ignore) || "yes".equals(ignore)||"true".equals(ignore)) {
this.ignore = true;
}
if(permitUrls!=null&&permitUrls.length()>0);
this.permitUrls=permitUrls.split(",");
this.gotoUrl=gotoUrl;
}
}
<filter>
<filter-name>encodeFilter</filter-name>
<filter-class>com.lwx.filter.EncodeFilter</filter-class>
<init-param>
<param-name>encode</param-name>
<param-value>GBK</param-value>
</init-param>
<init-param>
<param-name>ignore</param-name>
<param-value>false</param-value>
</init-param>
</filter>
<filter>
<filter-name>authorityFilter</filter-name>
<filter-class>com.lwx.filter.AuthorityFilter</filter-class>
<init-param>
<param-name>ignore</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>permitUrls</param-name>
<!-- 事實上 權限過濾器時將是否已登錄的功能剝離出來 爲了說明區別特意加了一個/manager/public.jsp-->
<param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp,/manager/,/manager/public.jsp,/error/noAuthority.jsp,/manager/user_list.jsp</param-value>
</init-param>
<init-param>
<param-name>gotoUrl</param-name>
<param-value>/error/noAuthority.jsp</param-value>
</init-param>
</filter>
<filter>
<filter-name>loginFilter</filter-name>
<filter-class>com.lwx.filter.LoginFilter</filter-class>
<init-param>
<param-name>ignore</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>permitUrls</param-name>
<param-value>/,/servlet/loginServlet?task=login,/index.jsp,/login/login.jsp</param-value>
</init-param>
<init-param>
<param-name>gotoUrl</param-name>
<param-value>/login/login.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>loginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>authorityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
這裏之所以把三個過濾器的配置都貼出來,及時說明下過濾器的順序跟
<filter-mapping>在web.xml中的順序有關