第16章 JAVA EE基础学习-MVC设计模式说明-过滤器概述等
程序员文章站
2022-05-23 08:38:22
...
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);
}
}
重点:
filter过滤器会出现一些异常。filter不能对同一个response多次重复重定向,也就是不能多次sendRedirect(“page.jsp”);否则会报错。
上一篇: jQuery 购物车功能