目录
一、JSTL中的Core标签库
1.<c:forEach>标签
在JSP页面中,经常需要对集合对象进行循环迭代操作,为此,Core标签库提供了一个
<c:forEach>标签,该标签专门用于迭代集合对象中的元素,如Set、List、Map、数组等,并且能重复执行标签体中的内容,它有两种语法格式,具体如下。
语法1:迭代包含多个对象的集合
<c:forEach [var="varName"] items="collection" [varStatus="varStatusName"]
[begin="begin"] [end="end"] [step="step"]>
body content
</c:forEach>
语法2:迭代指定范围内的集合
<c:forEach [var="varName"] [varStatus="varStatusName"] begin="begin"
end="end" [step="step"]>
body content
</c:forEach>
- var属性用于指定将当前迭代到的元素保存到page域中的名称。
- items属性用于指定将要迭代的集合对象。
- varStatus属性用干指定当前代状态信息的对象保存到page域中的名称。
- begin属性用于指定从集合中第几个元素开始进行迭代,begin的索引值从0开始。如果没有指定items属性,就从begin指定的值开始迭代,直到迭代结束为止。
- step属性用于指定迭代的步长,即迭代因子的增量。
-
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head></head> <body> <% String[] fruits = { "apple", "orange", "grape", "banana" }; %> String数组中的元素: <br /> <c:forEach var="name" items="<%=fruits%>"> ${name}<br /> </c:forEach> <% Map userMap = new HashMap(); userMap.put("Tom", "123"); userMap.put("Make", "123"); userMap.put("Lina", "123"); %> <hr/> HashMap集合中的元素: <br /> <c:forEach var="entry" items="<%=userMap%>"> ${entry.key} ${entry.value}<br /> </c:forEach> </body> </html>
<c:forEach>标签的begin、end和step属性分别用于指定循环的起始索引、结束索引和步长。使用这些属性可以迭代集合对象中某一范围内的元素。
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head></head> <body> colorsList集合(指定迭代范围和步长)<br /> <% List colorsList=new ArrayList(); colorsList.add("red"); colorsList.add("yellow"); colorsList.add("blue"); colorsList.add("green"); colorsList.add("black"); %> <c:forEach var="color" items="<%=colorsList%>" begin="1" end="3" step="2"> ${color} </c:forEach> </body> </html>
- count:表示元素在集合中的序号,从1开始计数。
- index:表示当前元素在集合中的索引,从0开始计数。
- first:表示当前是否为集合中的第1个元素。
- last:表示当前是否为集合中的最后一个元素。
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" import="java.util.*"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head></head> <body style="text-align: center;"> <% List userList = new ArrayList(); userList.add("Tom"); userList.add("Make"); userList.add("Lina"); %> <table border="1"> <tr> <td>序号</td> <td>索引</td> <td>是否为第一个元素</td> <td>是否为最后一个元素</td> <td>元素的值</td> </tr> <c:forEach var="name" items="<%=userList%>" varStatus="status"> <tr> <td>${status.count}</td> <td>${status.index}</td> <td>${status.first}</td> <td>${status.last}</td> <td>${name}</td> </tr> </c:forEach> </table> </body> </html>
2.<c:url> 标签
在访问一个JSP页面时,通常会在URL中传递一些参数信息。为了方便完成这种功能,Core
标签库中提供了一个<c:url>标签,该标签可以在JSP页面中构造一个新的地址,实现URL的重写。<c:url>标签有两语法格式,具体如下。
语法1:没有标签实体的情况
<c:url value="value" [context="context"] [var="varName"]
[scope="{page|request|session|application}"]>
语法2:有标签实体的情况,在标签体中指定构造URL参数
<c:url value="value"[context="context"] [var="varName"]
[scope="{page|request|session|application}"]>
<c:param>标签
</c:url>
- value属性用于指定构造的URL。
- context属性用于指定导入同一个服务器下其他Web应用的名称。
- Var属性用于指定将构造的URL地址保存到域对象的属性名称。
scope属性用于指定将构造好的URL保存到域对象中。
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" import="java.util.*"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head></head>
<body>
使用绝对路径构造URL:<br />
<c:url var="myURL"
value="http://localhost:8080/chapter07/register.jsp">
<c:param name="username" value="张三" />
<c:param name="country" value="中国" />
</c:url>
<a href="${myURL}">register.jsp</a><br />
使用相对路径构造URL:<br />
<c:url var="myURL"
value="register.jsp?username=Tom&country=France" />
<a href="${ myURL}">register.jsp</a>
</body>
</html>
二、Filter过滤器
1.什么是Filter
Filter被称作过滤器,其基本功能就是对Servlet容器调用Servlet的过程进行拦截,从而在
Servlet进行响应处理前后实现一些特殊功能。
注意:
过滤器是用来拦截请求和响应的,不能产生响应,而servlet是用来处理请求并产生响应的。
2.过滤器如何实现拦截?
1、当客户端发生请求后,在HttpServletRequest到达Servlet之前,过滤器拦截客户的HttpServletRequest
2、根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据
3、在过滤器中调用doFilter方法,对请求放行。请求到达Servlet后,对请求进行处理并产生HttpServletResponse发送给客户端
4、在HttpServletResponse到达客户端之前,过滤器拦截HttpServletResponse
5、根据需要检查HttpServletResponse,可以修改HttpServletResponse头和数据
6、最后,HttpServletResponse到达客户端
3.Filter生命周期
1、Filter接口中三个重要的方法
- init()方法:初始化参数,在创建Filter时自动调用,当我们需要设置初始化参数的时候,可以写到该方法中。
- doFilter()方法:拦截到要执行的请求时,doFilter就会执行。这里面写我们对请求和响应的预处理
- destory()方法:在销毁Filter时自动调用
-
package cn.itcast.chapter08.filter; import java.io.IOException; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class MyFilter extends HttpServlet { private static final long serialVersionUID = 1L; public MyFilter() { } public void destroy() { } protected void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException { response.setContentType("text/html;charset=utf-8"); System.out.println("输出内容表示拦截了响应"); response.getWriter().print("这是filter输出到网页的内容"); if(true) { chain.doFilter(request, response); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
在web.xml文件配置servlet
拦截MyServlet
package cn.itcast.chapter08.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyFilter extends HttpServlet {
private static final long serialVersionUID = 1L;
public MyFilter() {
}
public void destroy() {
}
protected void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {
response.setContentType("text/html;charset=utf-8");
System.out.println("输出内容表示拦截了响应");
response.getWriter().print("这是filter输出到网页的内容");
if(true)
{
chain.doFilter(request, response);
}
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
在web.xml文件配置servlet
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>cn.itcast.chapter08.filter.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/MyServlet</url-pattern>
</filter-mapping>
配置信息
(1)<filter>根元素用于注册一个Filter。
(2)<filter-name>子元素用于设置Filter名称。
(3)<filter-class>子元素用于设置Filter类的完整名称。
(4)<filter-mapping>根元素用于设置一个过滤器所拦截的资源。
(5)<filter-name>子元素必须与<filter>中的<filter-name>子元素相同。
(6)<url-pattern>子元素用于匹配用户请求的URL,例如“/MyServlet”,这个URL还可以使用通配符“*”来表示,例如“*.do”适用于所有以“.do”结尾的Servlet路径。
2.Filter映射
1.使用通配符“*”拦截用户的所有请求
Filter的<filter-mapping>元素用于配置过滤器拦截的资源信息,如果想让过滤器拦截所有的请求访问,那么需要使用通配符“*”来实现,具体示例如下。
<filter>
<filter-name>Filterl</filter-name>
<filter-class>cn.itcast.chapter08.filter.MyFilter</filter-class></filter>
<filter-mapping>
<filter-name>Filterl</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>
2.拦截不同方式的访问请求
在 web.xml文件中,一个<filter-mapping>元素用于配置一个Filter所负责拦截的资源。<filter-mapping>元素中有一个特殊的子元素<dispatcher>,该元素用于指定过滤器所拦截的资源被Servlet容器调用的方式,<dispatcher>元素的值共有4个,具体如下。
1) REQUEST
当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的 include()或forward()方法访问的,那么该过滤器将不会被调用。
2) INCLUDE
如果目标资源是通过RequestDispatcher的include()方法访问的,那么该过滤器将被调用。
程序
除此之外,该过滤器不会被调用。
1下。
3) FORWARD
如果目标资源是通过RequestDispatcher的forward()方法访问的,那么该过滤器将被调用。
除此之外,该过滤器不会被调用。
如果目标资源是通过声明式异常处理机制调用的,那么该过滤器将被调用。除此之外,过滤
4) ERROR
器不会被调用。
例 forwardservlet的servlet类用于将请求转发给first.jsp
package cn.itcast.chapter08.filter;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ForwardServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
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);
}
}
建一个first.jsp页面
建过滤器forwardfilter对first.jsp页面进行拦截
配置过滤器映射信息
说明没有拦截到forwardservlet转发的first.jsp
需要添加一个<dispatcher>
3.Filter链
在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称为一个Filter链.
web服务器根据Filter在web.xml文件中的注册顺序<mapping>,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传递给该方法.在doFilter方法中,开发人员如果调用了FilterChain对象doFilter方法,则Web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第二个filter,如果没有,则调用目标资源.
注意:
1.FilterChain.doFilter(request,response)它代表的是向下执行,如果下一个还是filter,那么访问这个filter,如果当前filter已经是整个链的末尾,那么访问web资源.
2.Filter的顺序由<Filter-mapping>的配置顺序决定.
<url-pattern>有几种写法:
1.完全匹配 必须以"/"开始
2.可以使用*通配符
-->1.目录匹配 /a/* /* 要求必须以"/"开始
-->2.扩展名匹配
*.do *.action 要求,不能以"/"开始,要以*.XXX结束.
例 新建两个过滤器myfiltero1,myfiltero2
package cn.itcast.chapter08.filter;
import java.io.*;
import javax.servlet.*;
public class MyFilter01 implements Filter {
public MyFilter01() {
super();
// TODO Auto-generated constructor stub
}
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 MyFilter01<br />");
chain.doFilter(request, response);
}
public void destroy() {
// 过滤器对象在销毁时自动调用,释放资源
}
}
package cn.itcast.chapter08.filter;
import java.io.*;
import javax.servlet.Filter;
import javax.servlet.*;
public class MyFilter02 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("MyFilter02 Before<br />");
chain.doFilter(request, response);
out.write("<br />MyFilter02 After<br />");
}
public void destroy() {
// 过滤器对象在销毁时自动调用,释放资源
}
}
配置过滤器myfiltero1,myfiltero2映射
4.FilterConfig接口
为了获取 Filter程序在 web.xml文件中的配置信息,Servlet API提供了一个FilterConfig 接口,该接口封装了Fiter程序在web.xml中的所有注册信息,并且提供了一系列获取这些配置信息的方法
例 子
package cn.itcast.chapter08.filter;
import java.io.*;
import javax.servlet.*;
public class MyFilter03 implements Filter {
public MyFilter03() {
super();
// TODO Auto-generated constructor stub
}
private String characterEncoding;
FilterConfig fc;
public void init(FilterConfig fConfig) throws ServletException {
// 获取FilterConfig对象
this.fc = fConfig;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 输出参数信息
characterEncoding=fc.getInitParameter("encoding");
System.out.println("encoding初始化参数的值为:"+characterEncoding);
chain.doFilter(request, response);
}
public void destroy() {
}
}
配置过滤器myfilter03映射
三、使用Filter实现用户自动登录
1.编写user类
2.实现登录页面和首页
用于显示用户的登录信息。如果没有用户登录,在index.jsp页面中就显示一个用户登录的超链接。如果用户已经登录,在index.jsp页面中显示登录的用户名,以及一个注销的超链接
3.编写loginservlet用于处理用户的登录请求
注销用户登录
4。创建过滤器
该类用于拦截用户登录的访问请求,判断请求中是否包含用户自动登录的Cookie。如果包含,则获取Cookie中的用户名和密码,并验证用户名和密码是否正确。如果正确,则将用户的登录信息封装到User对象存入Session域中,完成用户自动登录
5.配置映射信息
在web.xml文件中,配置所有相关Servlet及AutoLoginFilter过滤器信息。由于要拦截用户访问资源的所有请求,因此,将过滤器<filter-mapping>元素拦截的路径设置为“/*”
6.运行项目
四、使用Filter实现统一全站编码
1.编写form.jsp
2.创建servlet
3.创建过滤器
4.配置映射信息
5.启动项目,测试结果
登录按钮实现登录使用的POST,可以解决中文乱码,单击超链接登录使用的GET,可以解决中文乱码
可以看出,GET方式提交表单与POST方式提交表单的效果是一样的,同样不会
出现乱码问题。因此,可以说明使用Fiter过滤器可以方便地完成统一全站编码的功能。