1 基础的MVC理解图如下:
我们在开发中,常常采用MVC模式进行开发程序,但是在web中,我们常常采用JSP、HTML做界面View,然后Servlet做控制器Control,最后是数据模型Data Model和业务模型Business Model。
2 过滤器的理解图:
2.1 过滤器 :
我们项目中的某些资源我们并不想让客户直接访问,简单来说我们希望用户在登录之后才能访问我们的资源。于是我们就开始权限控制的道路上奔跑。Servlet中,我们可以很简单的做到这一步,就是增加过滤器filter类。然后配置web.xml进行配合编码完成我们的权限控制业务。
简单的过滤器案例:
字符编码过滤器
/** * 工 程 名:SMS-20180522 <br> * 文 件 名:CharacterEncodeFilter.java <br> * 工具包名:edu.fjnu.training.filter <br> * 功能描述:TODO <br> * 创建时间:2018年5月22日 下午9:13:57 <br> * 版本信息:V1.0 * @创建人:周开伦 */ package edu.fjnu.training.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; /** * 类名:CharacterEncodeFilter <br> * 功能描述: <br> * 创建日期:2018年5月22日 下午9:13:57 <br> * 修改备注: * @作者信息:Zhou kailun <br> */ public class CharacterEncodeFilter implements Filter { /**<p>构造函数:</p><br><br> * <p>描述:</p><br> */ public CharacterEncodeFilter() { } /* (非 Javadoc) * <p>Title:destroy</p> * <p>描 述:</p> * @see javax.servlet.Filter#destroy() */ @Override public void destroy() { } /* (非 Javadoc) * <p>Title:doFilter</p> * <p>描 述:</p> * @param paramServletRequest * @param paramServletResponse * @param paramFilterChain * @throws IOException * @throws ServletException * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { //控制字符编码必须为utf-8过滤器 request.setCharacterEncoding("utf-8"); filterChain.doFilter(request, response);//放行继续下一步过滤操作直到访问到资源 } /* (非 Javadoc) * <p>Title:init</p> * <p>描 述:</p> * @param paramFilterConfig * @throws ServletException * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) */ @Override public void init(FilterConfig paramFilterConfig) throws ServletException { } }
身份验证过滤器:
/** * 工 程 名:SMS-20180522 <br> * 文 件 名:AuthenFilter.java <br> * 工具包名:edu.fjnu.training.filter <br> * 功能描述:TODO <br> * 创建时间:2018年5月22日 下午9:27:31 <br> * 版本信息:V1.0 * @创建人:周开伦 */ package edu.fjnu.training.filter; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 类名:AuthenFilter 身份验证过滤器<br> * 功能描述: <br> * 创建日期:2018年5月22日 下午9:27:31 <br> * 修改备注: * @作者信息:Zhou kailun <br> */ public class AuthenFilter implements Filter { /**<p>构造函数:</p><br><br> * <p>描述:</p><br> */ public AuthenFilter() { } /* (非 Javadoc) * <p>Title:init</p> * <p>描 述:</p> * @param paramFilterConfig * @throws ServletException * @see javax.servlet.Filter#init(javax.servlet.FilterConfig) */ @Override public void init(FilterConfig paramFilterConfig) throws ServletException { } /* (非 Javadoc) * <p>Title:doFilter</p> * <p>描 述:</p> * @param paramServletRequest * @param paramServletResponse * @param paramFilterChain * @throws IOException * @throws ServletException * @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse, javax.servlet.FilterChain) */ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest req=(HttpServletRequest)request; HttpServletResponse res=(HttpServletResponse)response; String uri=req.getRequestURI(); String resource=uri.substring(uri.lastIndexOf("/")+1); System.out.println("resource:"+resource); if(resource.contains("smsMgr")){ Object obj=(Object)req.getSession().getAttribute("loginedUser"); if(obj==null){ res.sendRedirect("securityMgr?act=toLogin"); } else{ filterChain.doFilter(request, response); } } else filterChain.doFilter(request, response); } /* (非 Javadoc) * <p>Title:destroy</p> * <p>描 述:</p> * @see javax.servlet.Filter#destroy() */ @Override public void destroy() { } }
web.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <filter> <filter-name>AuthenFilter</filter-name> <description>这是我自己写的过滤器,拦截所有访问路径的操作,只要对我这个程序进行访问的请求我都进行身份验证</description> <filter-class>edu.fjnu.training.filter.AuthenFilter</filter-class> </filter> <filter> <filter-name>CharacterEncodeFilter</filter-name> <description>这是我自己写的过滤器,拦截所有访问路径的操作,只要对我这个程序进行访问的请求我都拦截</description> <filter-class>edu.fjnu.training.filter.CharacterEncodeFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEncodeFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter-mapping> <filter-name>AuthenFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>StudentMgrServlet</servlet-name> <display-name>This is the display name of my J2EE component</display-name> <description>This is the description of my J2EE component</description> <servlet-class>edu.fjnu.training.conrtoller.StudentMgrServlet</servlet-class> </servlet> <servlet> <servlet-name>SecurityMgrServlet</servlet-name> <display-name>This is the display name of my J2EE component</display-name> <description>This is the description of my J2EE component</description> <servlet-class>edu.fjnu.training.conrtoller.SecurityMgrServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>StudentMgrServlet</servlet-name> <url-pattern>/smsMgr</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>SecurityMgrServlet</servlet-name> <url-pattern>/securityMgr</url-pattern> </servlet-mapping> <!-- 设置所有jsps文件夹下的jsp文件不能直接被访问 --> <security-constraint> <web-resource-collection> <web-resource-name>jsp-pages</web-resource-name> <url-pattern>/jsps/*</url-pattern><!-- 所有/jsps/文件下的文件都不能别访问 --> </web-resource-collection> <auth-constraint/> </security-constraint> <login-config> <auth-method>BASIC</auth-method> </login-config> </web-app>
filter过滤器的先后顺序:
依据其在web.xml 中的filter-mapping顺序有关,排在前面的优先级最先验证。以上是先进行编码认证,在进行身份认证。
然后我们看一些辅助代码:
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> <jsp:forward page="securityMgr?act=toLogin"></jsp:forward> </body> </html>
login.jsp:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" isELIgnored="false"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>登录操作</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <style type="text/css"> .error{ border:1px groove yellow; color:red; width:200px; } </style> </head> <body> <h3>登录界面请登录</h3> <form action="<c:url value="/securityMgr"></c:url>?act=login" method="post"> <div> <span>账号:</span> <input type="text" name="userNo" value="${param.userNo }"> </div> <div> <span>密码:</span> <input type="password" name="userPwd"> </div> <c:if test="${not empty errMsg}"> <div class="error">${errMsg }</div> </c:if> <div> <input type="submit" value="登录"> </div> </form> <%@ include file="/jsps/footer.jsp" %> </body> </html>main.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" isELIgnored="false"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'index.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script> function exitSys(){ if(confirm("您确定要退出系统吗?")){ location.href="<c:url value="/securityMgr"></c:url>?act=logout"; } } </script> </head> <body> <h3>学生管理系统</h3> <div style="text-align:right;float:right;padding-right:10px;"> 操作员:${loginedUser.userName }<button style="margin-left:5px;" onclick="exitSys();">退出</button> </div> <ul> <li><a href="<c:url value="/smsMgr"/>?act=toReg">新生注册登记</a></li> <li><a href="<c:url value="/smsMgr"/>?act=loadall">学生列表</a></li> </ul> </body> </html>
footer.jsp:
<%@ page language="java" import="java.util.*,edu.fjnu.training.config.VersionInfo" pageEncoding="utf-8"%> <hr> <div style="text-align:center;color:gray;font-size:12px;"> <%=VersionInfo.buildFooterStr() %> </div>
SecurityMgrServlet.java 安全登录管理Servlet
package edu.fjnu.training.conrtoller; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import edu.fjnu.training.domain.User; import edu.fjnu.training.exception.DataAccessException; import edu.fjnu.training.exception.SMSException; import edu.fjnu.training.service.UserService; import edu.fjnu.training.service.UserServiceImpl; public class SecurityMgrServlet extends HttpServlet { /**默认编码方式:*/ private static final String ENCODE="utf-8"; /** * Constructor of the object. */ public SecurityMgrServlet() { super(); } /** * The doGet method of the servlet. <br> * * This method is called when a form has its tag value method equals to get. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //request.setCharacterEncoding(ENCODE); String act=request.getParameter("act"); if("toLogin".equals(act)){ request.getRequestDispatcher("jsps/security/login.jsp").forward(request, response); } else if("login".equals(act)){ String userNo=request.getParameter("userNo"); String userPwd=request.getParameter("userPwd"); UserService userService=new UserServiceImpl(); User user=null; try{ user=userService.checkUser(userNo, userPwd); request.getSession().setAttribute("loginedUser", user); response.sendRedirect("securityMgr?act=main");; }catch(SMSException e){ request.setAttribute("errMsg", e.getMessage()); request.getRequestDispatcher("/jsps/security/login.jsp").forward(request, response); } } else if("main".equals(act)){ request.getRequestDispatcher("/jsps/main.jsp").forward(request, response); } else if("logout".equals(act)){ request.getSession().removeAttribute("loginedUser"); request.getSession().invalidate(); response.sendRedirect("securityMgr?act=toLogin"); } } /** * The doPost method of the servlet. <br> * * This method is called when a form has its tag value method equals to post. * * @param request the request send by the client to the server * @param response the response send by the server to the client * @throws ServletException if an error occurred * @throws IOException if an error occurred */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } }