第十章 过滤器
Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:
在web应用可以部署多个过滤器,这些过滤器组成过一个链(过滤器链)来执行多个操作或者查;
只有当客户端的请求通过这个过滤链的检查后,才能将请求发送到目的组件,如果请求不能通过过滤链中某一个过滤器,那么请求就会被阻止。
过滤器生命周期的各个阶段:
Filter实现步骤:
编写java类实现Filter接口,并实现其doFilter方法。
package com.silvan.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;
public class FilterDemo1 implements Filter{
public FilterDemo1() { System.out.println("********FilterDemo1 实例化***********"); }
@Override public void destroy() { // TODO Auto-generated method stub System.out.println("********FilterDemo1 destroy***********"); }
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub System.out.println("********FilterDemo1 doFilter chain 前***********"); // 默认:对目标资源进行了拦截,目标资源没有被访问 // 如果访问请求调用链下一个资源 chain.doFilter(request, response); System.out.println("********FilterDemo1 doFilter chain 后***********"); }
@Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub System.out.println("********FilterDemo1 init***********"); } } |
在 web.xml 文件中使用<filter>和<filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。<url-pattern>/*</url-pattern>表示对所有访问进行拦截。
<filter> <filter-name>FilterDemo1</filter-name> <filter-class>com.silvan.filter.FilterDemo1</filter-class> </filter>
<filter-mapping> <filter-name>FilterDemo1</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
访问http://localhost:8081/08Servlet/,显示:
FilterConfig对象的使用方法:
@Override public void init(FilterConfig filterConfig) throws ServletException { // TODO Auto-generated method stub System.out.println("********Filter2 init***********"); // 获取过滤器名字 String filtername = filterConfig.getFilterName(); System.out.println("********Filter2 filtername***********" + filtername); // 功能一:获取配置初始化参数,需要在web.xml中配置 String uname = filterConfig.getInitParameter("uname"); System.out.println("********Filter2 uname***********" + uname); // 功能二:读取WEB资源文件 必须获取绝对磁盘路径 String filePath = filterConfig.getServletContext().getRealPath("/WEB-INF/info.txt"); try { BufferedReader reader = new BufferedReader(new FileReader(filePath)); System.out.println(reader.readLine()); reader.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } |
案例:
禁止某个IP访问站点
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub System.out.println("---------IPFilterDemo1 doFilter"); // 获取客户端IP地址 String clientIP = request.getRemoteAddr(); // 强制类型转换,为了使用跳转方法 HttpServletResponse httpServletResponse = (HttpServletResponse) response; if ("127.0.0.1".equals(clientIP)) { //自己创建一个错误输出页面error.jsp httpServletResponse.sendRedirect("error.jsp"); } else { chain.doFilter(request, response); } } |
设置字符编码集
@Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub System.out.println("---------EncodingFilter doFilter"); // 如果用户输入中文,对中文请求内容处理 request.setCharacterEncoding("utf-8"); // 将中文输出到页面上,设置响应字符集 response.setContentType("text/html;charset=utf-8"); chain.doFilter(request, response); } |
第十一章 Servlet MVC模式
MVC模式的核心思想是有效地组合“视图”、“模型”和“控制器”。掌握MVC模式对于设计合理的Web应用框架有着十分重要的意义。
JSP开发的两种模型(Model1/Model2)
模型1:
- 使用JSP+JavaBeans将页面显示和业务逻辑处理分开
- JSP实现页面显示,响应请求并将结果返回给客户
- JavaBean对象保存数据和实现业务逻辑
优点:实现了页面显示与业务逻辑的分离
缺点:需要在JSP页面控制流程转向并且调用JavaBean代码;业务逻辑复杂时,JSP编写变得复杂
案例
Jsp+javaBeans模式简单计算器:
Calculator.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>calculator</title> <script type="text/javascript"> function checkForm(){ // 对需要校验字段 添加 id 属性 var first = document.getElementById("first").value; var second = document.getElementById("second").value; var operator = document.getElementById("operator").value; // 判断参数必须为数字 if(isNaN(first) || isNaN(second)){ // isNaN is not a number alert("输入参数 必须为数字!"); return false; } if(second==0 && operator == '/'){ alert("除数不能为0!"); return false; } } </script> </head> <body> <!-- 计算器页面 -->
<!-- 计算结果 --> <jsp:useBean id="calculator" class="com.silvan.pojo.CalculatorDemo1" scope="page"></jsp:useBean> <!-- 当用户提交form 自动封装 数据 --> <jsp:setProperty property="*" name="calculator"/>
<h3>计算结果是 :${calculator.firstNum } ${calculator.operator } ${calculator.secondNum } = ${calculator.result }</h3> <hr/> <!-- 计算form表单 --> <h3>简单的计算器</h3> <form action="/lesson11/calculator.jsp" method="post" onsubmit="checkForm();"> <table> <tr> <td>第一个参数</td> <td> <!-- 使用 setProperty * form输入项name 必须和 javabean类属性一致 --> <input type="text" name="firstNum" id="first"/> </td> </tr> <tr> <td>运算符</td> <td> <select name="operator" id="operator"> <option value="+">+</option> <option value="-">-</option> <option value="*">*</option> <option value="/">/</option> </select> </td> </tr> <tr> <td>第二个参数</td> <td> <input type="text" name="secondNum" id="second" /> </td> </tr> <tr> <td colspan="2"> <input type="submit" value="计算"/> </td> </tr> </table> </form> </body> </html> |
CalculatorDemo1.java
package com.silvan.pojo; /** * 計算類 * @author Administrator */ public class CalculatorDemo1 { private String firstNum = "0"; // 参数一 private String secondNum = "0"; // 参数二 private String operator = "+"; // 运算符 private double result; // 运算结果
public String getFirstNum() { return firstNum; }
public void setFirstNum(String firstNum) { this.firstNum = firstNum; }
public String getSecondNum() { return secondNum; }
public void setSecondNum(String secondNum) { this.secondNum = secondNum; }
public String getOperator() { return operator; }
public void setOperator(String operator) { this.operator = operator; }
public double getResult() { // 将运算逻辑写到这里 Double a = Double.parseDouble(firstNum); Double b = Double.parseDouble(secondNum); Double result = 0.0; if (operator.equals("+")) { result = a + b; } else if (operator.equals("-")) { result = a - b; } else if (operator.equals("*")) { result = a * b; } else if (operator.equals("/")) { result = a / b; } return result; }
public void setResult(double result) { this.result = result; } } |
模型2
- 将模型1中JSP嵌入的流程控制和部分逻辑处理代码提取至一个单独的角色:控制器
- 模型2是MVC架构模式在WEB开发中的应用
MVC简介:
MVC是一种设计模式,由Trygve为发展SmallTalk在1978年提出的,出现在GUI设计中。MVC按功能对各种对象进行分割,目的是为了将对象的耦合程度降至最低。
- 模型(Model)——封装了最核心的功能,用于存储数据以及处理用户请求的业务逻辑。
- 视图(View)——系统和用户交互的界面,从模型那获得数据并表现数据,同时将用户请求通知通知器。
- 控制器(Controller)——扮演调度者的角色,,即控制器根据视图提出的请求判断将请求和数据交给那个模型处理,处理后的有关结果交给哪个视图更新显示
JSP中的MVC模式:
- 模型(Model):一个或多个JavaBean对象,用于存储数据和处理数据;
- 视图(View):一个或多个JSP页面,为模型提供数据显示,JSP页面主要使用 HTML标记和JavaBean标记来显示数据。
- 控制器(Controller):一个或多个Servlet对象,根据视图提交的请求进行控制,生成JavaBean实例输出给JSP页面.
模型2实例
JSP中的MVC模式计算器
视图层Calculator.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>calculator</title> <script type="text/javascript"> function checkForm(){ // 对需要校验字段 添加 id 属性 var first = document.getElementById("first").value; var second = document.getElementById("second").value; var operator = document.getElementById("operator").value; // 判断参数必须为数字 if(isNaN(first) || isNaN(second)){ // isNaN is not a number alert("输入参数 必须为数字!"); return false; } if(second==0 && operator == '/'){ alert("除数不能为0!"); return false; } } </script> </head> <body> <!-- 计算form表单 --> <h3>简单的计算器</h3> <form action="/lesson11/CalculatorServletDemo2" method="post" onsubmit="checkForm();"> <table> <tr> <td>第一个参数</td> <td> <!-- 使用 setProperty * form输入项name 必须和 javabean类属性一致 --> <input type="text" name="firstNum" id="first"/> </td> </tr> <tr> <td>运算符</td> <td> <select name="operator" id="operator"> <option value="+">+</option> <option value="-">-</option> <option value="*">*</option> <option value="/">/</option> </select> </td> </tr> <tr> <td>第二个参数</td> <td> <input type="text" name="secondNum" id="second" /> </td> </tr> <tr> <td colspan="2"> <input type="submit" value="计算"/> </td> </tr> </table> </form> </body> </html> |
控制层CalculatorServletDemo2.java
package com.silvan.servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import com.silvan.pojo.CalculatorDemo2; public class CalculatorServletDemo2 extends HttpServlet { /** * Constructor of the object. */ public CalculatorServletDemo2() { super(); } /** * Destruction of the servlet. <br> */ public void destroy() { super.destroy(); // Just puts "destroy" string in log // Put your code here } /** * 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 { //取出计算值 double firstNum = Double.parseDouble(request.getParameter("firstNum")); double secondNum = Double.parseDouble(request.getParameter("secondNum")); String operator = request.getParameter("operator"); double result = 0; //计算结果 if (operator.equals("+")) { result = firstNum + secondNum; } else if (operator.equals("-")) { result = firstNum - secondNum; } else if (operator.equals("*")) { result = firstNum * secondNum; } else if (operator.equals("/")) { result = firstNum / secondNum; } //将数据存入bean中 CalculatorDemo2 dataBean = new CalculatorDemo2(); dataBean.setFirstNum(firstNum); dataBean.setSecondNum(secondNum); dataBean.setOperator(operator); dataBean.setResult(result); request.setAttribute("bean", dataBean); //跳转到结果显示界面 request.getRequestDispatcher("/demo2/showResult.jsp").forward(request, response);
} /** * 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 { doGet(request, response); } /** * Initialization of the servlet. <br> * * @throws ServletException if an error occurs */ public void init() throws ServletException { // Put your code here } } |
模型层CalculatorDemo2.java
package com.silvan.pojo; public class CalculatorDemo2 { private double firstNum; // 参数一 private double secondNum; // 参数二 private String operator; // 运算符 private double result; // 运算结果
public double getFirstNum() { return firstNum; }
public void setFirstNum(double firstNum) { this.firstNum = firstNum; }
public double getSecondNum() { return secondNum; }
public void setSecondNum(double secondNum) { this.secondNum = secondNum; }
public String getOperator() { return operator; }
public void setOperator(String operator) { this.operator = operator; }
public double getResult() { return result; }
public void setResult(double result) { this.result = result; }
} |
视图层showResult.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>calculator</title> </head> <body> <h3>运算结果</h3> <jsp:useBean id="bean" type="com.silvan.pojo.CalculatorDemo2" scope="request"></jsp:useBean> <jsp:getProperty property="firstNum" name="bean"/> <jsp:getProperty property="operator" name="bean"/> <jsp:getProperty property="secondNum" name="bean"/> = <jsp:getProperty property="result" name="bean"/> </body> </html> |