一、JSTL简介:
JSTL全名为JavaServer Pages Standard Tag Library,中文名称为JSP标准标签函数库,目前最新的版本为1.2。JSTL是由JCP(Java Community Process)所指定的标准规格,它主要提供给Java Web开发人员一个标准通用的标签函数库。
JSTL所提供的标签函数库主要分为五大类:
(1)核心标签库 (Core tag library)
(2)I18N 格式标签库 (I18N-capable formatting tag library)
(3)SQL 标签库 (SQL tag library)
(4)XML 标签库 (XML tag library)
(5)函数标签库 (Functions tag library
核心标签库 (Core tag library)主要有以下几种:
1、表达式标签:
(1)<c:out>:主要用来显示数据的内容,就像是 <%= scripting-language %> 一样
(2)<c:set>:主要用来将变量储存至JSP范围中或是JavaBean的属性中
(3)<c:remove>:主要用来移除变量
(4)<c:catch>:主要用来处理产生错误的异常状况,并且将错误信息储存起来(用的少)
2、流程控制:
(1)<c:if>:用途和我们一般在程序中用的if 一样
(2):本身只当做 <c:when> 和 <c:otherwise> 的父标签
(3)/:使用<c:when>和<c:otherwise>来做流程控制时,两者都必须为<c:choose>的子标签(类似于switch···case···)
3、迭代操作:
:循环遍历,它可以将集合(Collection)中的成员循序浏览一遍。运作方式为当条件符合时,就会持续重复执行<c:forEach>的本体内容。
:用来浏览一字符串中所有的成员,其成员是由定义符号(delimiters)所分隔的。
二、核心标签库:
包含Web应用的常见工作, 比如:循环、表达式赋值、 基本输入输出等。
1、表达式标签:
(1)<c:out>:主要用来显示数据的内容,就像是 <%= scripting-language %> 一样
(2)<c:set>:主要用来将变量储存至JSP范围中或是JavaBean的属性中
(3)<c:remove>:主要用来移除变量
(4)<c:catch>:主要用来处理产生错误的异常状况,并且将错误信息储存起来(用的少)
(5)<c:out>标签
新建JavaWeb工程chapter07,index.jsp代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!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>Insert title here</title> <% request.setAttribute("name", "smyhvae"); %> </head> <body> <c:out value="${requestScope.name} "></c:out> </body> </html>
(6)<c:set>标签
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!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>Insert title here</title> <% request.setAttribute("name", "smyhvae"); %> </head> <body> <%--输出标签 --%> <c:out value="${requestScope.name} "></c:out> <%--定义变量标签 --%> <c:set var="age" value="22"></c:set> ${age } </body> </html>
2、流程控制:
(1)<c:if>:用途和我们一般在程序中用的if 一样
(2):本身只当做 <c:when> 和 <c:otherwise> 的父标签
(3)/:使用<c:when>和<c:otherwise>来做流程控制时,两者都必须为<c:choose>的子标签(类似于switch···case···)
3、迭代操作:
(1):循环遍历,它可以将集合(Collection)中的成员循序浏览一遍。运作方式为当条件符合时,就会持续重复执行<c:forEach>的本体内容。
(2):用来浏览一字符串中所有的成员,其成员是由定义符号(delimiters)所分隔的。
代码举例:
(3)
新建类User,作为遍历的对象。User.java代码如下:
package com.vae.bean; public class User { private String name; private String sex; private int age; public User() { super(); } public User(String name, String sex, int age) { super(); this.name = name; this.sex = sex; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [name=" + name + ", sex=" + sex + ", age=" + age + "]"; } }
新建文件index3.jsp,代码如下:
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@page import="com.vae.bean.User,java.util.*"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <!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>Insert title here</title> <% List<User> users = new ArrayList<User>(); User u1 = new User("生命壹号", "男", 22); User u2 = new User("生命二号", "男", 23); User u3 = new User("vae", "女", 24); users.add(u1); users.add(u2); users.add(u3); request.setAttribute("users", users); %> </head> <body> <table border="1"> <tr> <th>name</th> <th>sex</th> <th>age</th> </tr> <c:forEach items="${requestScope.users }" var="user"> <tr> <td>${user.name}</td> <td>${user.sex}</td> <td>${user.age}</td> </tr> </c:forEach> </body> </html>
运行结果:
(4)中的属性:
· begin:表示从第几个开始索引,一般不写;
· end:表示结束的位置。如果需要遍历十行,在此处写10即可。
·step:增量。
上面的三个属性用的比较少。
· varStatus:当前的状态。它的状态有以下几个:
index 索引 从0开始 count 从1开始 当前遍历次数 current 当前正在迭代的对象 first 是否是第一个 last 是否是最后一个
一、什么是Filter
1.Filter概念
Filter 不是一个servlet,它不能产生一个response,但是它能够在一个request到达servlet之前预处理request,也可以在 response离开servlet时处理response。换句话说,filter其实是客户端与servlet中间的一个传递者,并且它可以对要传递 的东西进行修改。过滤作用,对从客户端向服务器端发送的请求进行过滤,也可以对服务器端返回的响应进行处理。它使用户可以改变一个request和修改一个 response.。
注意:过滤器是用来拦截请求和响应的,不能产生响应,而servlet是用来处理请求并产生响应的。
2.简单的Filter示例
package cn.itacst.chapter08.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.annotation.WebFilter; /** * Servlet Filter implementation class MyFilter */ @WebFilter("/MyFilter") public class MyFilter implements Filter { /** * Default constructor. */ public MyFilter() { // TODO Auto-generated constructor stub } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // TODO Auto-generated method stub // place your code here response.setContentType("test/html;charset=utf-8"); response.getWriter().print("进入filter"); // pass the request along the filter chain String name=request.getParameter("name"); System.out.println(name); if("dashuju".equals(name)) { chain.doFilter(request, response); } response.getWriter().print("退出filter"); } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub } }
二、.Filter的两种映射方式
1.使用通配符*拦截用户的所有请求
Filter 的 元素用于配置过滤器拦截的资源信息,如果想让过滤器拦截所有的请求,那么可以使用通配符*实现,具体实现方式如下:
<filter> <filter-name>MyFilter</filter-name> <filter-class>com.mengma.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2.拦截不同方式的访问请求
在 web.xml 文件中,每一个 元素都可以配置一个 Filter 所负责拦截的资源。在 元素中有一个特殊的子元素 ,该元素用于指定过滤器所拦截的资源被 Servlet 容器调用的方式。 元素的值共有四个,如表 所示。
(1)创建ForwardServlet
package com.mengma.filter; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ForwardServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/first.jsp").forward(request, response); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
(2)创建 first.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="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>Insert title here</title> </head> <body> first.jsp </body> </html>
(3)创建并编辑过滤器 ForwardFilter
package com.mengma.filter; import java.io.IOException; import java.io.PrintWriter; 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 ForwardFilter implements Filter { public void init(FilterConfig fConfig) throws ServletException { // 过滤对象在初始化时调用,可以配置一些初始化参数 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { // 用于拦截用户的请求,如果和当前过滤器的拦截路径匹配,该方法会被调用 PrintWriter out = response.getWriter(); out.write("Hello FilterTest"); } public void destroy() { // 过滤器对象在销毁时自动调用,释放资源 } }
此时需在 web.xml 文件中添加 ForwardFilter 的映射信息。代码中增加了一个 子元素,并且该元素的值为 FORWARD,如下所示:
<filter> <filter-name>ForwardFilter</filter-name> <filter-class>com.mengma.filter.ForwardFilter</filter-class> </filter> <filter-mapping> <filter-name>ForwardFilter</filter-name> <url-pattern>/first.jsp</url-pattern> <dispatcher>FORWARD</dispatcher> </filter-mapping>
三、Filter链
web.xml配置了filter过滤器,在容器启动的时候执行了init()方法进行了初始化,然后在容器关闭的时候执行了destroy()方法销毁过滤器,在每次服务器接受请求的时候每次都会先过一遍过滤器,如果有合适的过滤器就会执行相应过滤器的doFilter方法。
类似这种相同匹配模式的过滤器会存在于同一个过滤链中,然后按照初始化的先后顺一次排列,实现逐层过滤。其中filterChain中有个doFilter方法,他的作用是将当前请求转发给过滤链中的下一个过滤器进行过滤,然后将过滤结果,只有等待下一个过滤器执行过滤完成后才能继续执行。该执行过程类似如下图:
如上图,通过过滤链逐层执行过滤就像一层嵌套,一层套一层,如果过滤链中只有一个过滤器(或者执行到最后一个)的话,执行了chain.doFilter()他会直接将请求转发出去,获取request resource资源,因为从始至终都是同一个request和response在传递,所以每次过滤都可以修改请求或返回结果,实现了过滤修改的目的。
代码实例:
ResponseFilter.java
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { CustomResponseWrapper customResponseWrapper = new CustomResponseWrapper((HttpServletResponse) servletResponse); System.out.println("ResponseFilter 执行前"); filterChain.doFilter(servletRequest,customResponseWrapper);//执行下一层过滤 System.out.println("ResponseFilter 执行后"); } }
SecondFilter.java
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 2 System.out.println("Second doFilter执行前"); 3 filterChain.doFilter(servletRequest,servletResponse);//这是最后一层过滤器,会直接请求resource 4 System.out.println("Second doFilter执行后"); 5 }
web.xml (两个过滤器使用了相同的匹配模式‘/*’,所以会处于同一过滤链中)
<filter> <filter-name>ResponseFilter</filter-name> <filter-class>filter.ResponseFilter</filter-class> </filter> <filter-mapping> <filter-name>ResponseFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>SecondFilter</filter-name> <filter-class>filter.SecondFilter</filter-class> </filter> <filter-mapping> <filter-name>SecondFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>