JSP/Servlet 及相关笔记

JSP

web工程文件组织

<webDemo>

|-WEB-INF

|-classes 保存单个*.class文件

|-lib 保存打包后的JAR文件

|-web.xml

|-<a.jsp>

 

错误页面

<%@page contentType="text/html; charset=GBK"

Language="java" errorPage="error.jsp" %>

<%

Int a = 6;

Int c = a/0;

%>

 

<%@page contentType="text/html; charset=GBK"

Language="java"  isErrorPage="true" %>

异常类型:<%=exception.getClass()%>

异常信息:<%=exception.getMessage()%>

IE要打开Internet选项-高级-显示友好HTTP错误信息

 

静态包含&动态包含

静态包含:相当于被包含页面直接放到包含页来,然后再进行编译执行。

语法:

<%@ include file="路径名" %>

动态包含:被包含页先进行执行后才放到包含页。其中分为两种,一种为不带参数的,一种为带参数的。语法分别是:

(1)不带参数:

<jsp:include page="bottom.jsp"/>

(2)带参数:   

<jsp:include page="bottom.jsp"/>

<jsp:param value="这是参数" name="参数名" />

</jsp:include>

带参数的可以将参数传递到被包含页,也就是说,上面的例子中,可以在bottom.jsp中接收参数,接收的语句如下:

<%

request.setCharacterEncoding("GBK");

String dongtai=request.getParameter("dongtai");

%>

下面列出两个页面的完整代码:

(1)includedemo.jsp

<%@ page contentType="text/html; charset=GBK" %>

<html>

<body>

<head>

<title>包含指令的练习</title>

</head>

<%request.setCharacterEncoding("GBK"); %>

<jsp:include page="bottom.jsp">

<jsp:param value="这是参数" name="dongtai" />

</jsp:include>

(2)bottom.jsp

<%@ page contentType="text/html; charset=GBK" %>

<%

request.setCharacterEncoding("GBK");

String dongtai=request.getParameter("dongtai"); %>

<font size="3"><% out.print(dongtai);%></font>

<font size="4">大家好</font>

</body>

</html>

区别:

1.静态导入是将被导入的页面完全融合,两个页面融合成一个完整的Servlet,而动态导入是在Servlet中使用include方法来引入被导入的页面。

2.静态导入时被导入的页面编译指令会起作用,而动态导入的页面编译指令失效,只是插入被导入页面的body内容。

3.动态包含还可以增加额外的参数。

jsp:forward指令

<!--jsp-forward.jsp-->

<jsp:forward page="forward-result.jsp">

<jsp:param name="age" value="29"/>

</jsp:forward>

 

<!--forward-result.jsp-->

<%=result.getParameter("age")>

执行forward指令时,用户请求的地址不变,但页面内容转向forward页面。

<!--form.jsp-->

<form id="login" method="post" action="jsp-forward.jsp">

<input type="text" name="username">

<input type="submit" value="login">

</form>

<!--forward-result.jsp-->

<%=result.getParameter("age")>

<%=result.getParameter("username")>

这样forward-result.jsp不仅可以输出forward指令增加的请求参数,还可以看到表单username表单域 对应的请求参数。

 

服务器端跳转与客户端跳转:

 

    首先我们需要理解什么是服务器端跳转,什么是客户端的跳转。

    简单理解所谓服务器端跳转就是指地址栏内容不变(客户端浏览器的地址栏不会显示目标地址的URL),//注:客户端请求到达以后,服务器发现当前资源给不出回应,要在服务器内部请求另一个资源的跳转。所以,1.跳转与否客户端不知道(URL不变),2.属于一次request

    而客户端跳转是指地址栏内容发生改变(客户端向服务器发请求后,然后服务器再给客户端一个响应,然后客户端再根据服务器端给的响应中的URL再向服务器发送请求,所以是两次请求,因此地址栏改变了显示最后一次请求地址);//注:客户端请求到达服务端,服务端返回一个 “去访问其他链接” 的回应,客户端依此回应,第二次去访问。所以:1.客户端根据回应地址又跳转了一次,2.第二次跳转后,已经出了request的属性范围

Java中服务器端跳转

    1、request.getRequestDispatcher("success.jsp").forward(request,response),它是只要执行到此语句之后则立刻进行跳转,可以传递request属性;

    2、<jsp:forward>,这种跳转属于无条件跳转,它只能在栈内转,而sendRedirect中则可以任意转,甚至可以输入baidu;//注:无条件跳转后,此跳转语句后边的代码都不会被执行(比如关闭数据库一类的)

 

客户端跳转:

    1、response.sendRedirect("fail.jsp"),所有页面执行完之后再进行跳转,不能传递request范围的属性,但是可以通过地址重写的方式向跳转页传递参数,因为该方法执行完之后就相当于一次http request的结束,这是服务器会向客户端发送302状态码和新的url,告诉客户端重新发送request请求到新的url,然后客户端照此执行,执行即新的请求响应流程开始,服务器再重新创建HttpServletRequest对象和HttpServletResponse对象,此时两个请求已经不在一个线程了,所以request和response对象都不是开始的那个了;

    2、response.setHeader("refresh","2;URL=index.jsp"),2秒后跳转到其他页面;

    3、<a href="http://www.baidu.com">百度</a>,超链接;

    4、表单提交;

通过以上可以得知,如果现在一个页面中使用了JDBC,则应该在forward跳转之前关闭数据库链接,而使用respose则可以在任意的位置处关闭;

 

 

useBean,setProperty,getProperty

<jsp:useBean id="p1" class="lee.Person" scope="page"/>

<jsp:setProperty name="p1" property="name" value="wawa"/>

<jsp:setProperty name="p1" property="age" value="23"/>

<jsp:getProperty name="p1" property="name"><br/>

<jsp:getProperty name="p1" property="age">

和下面相同

<%

Person p1=new Person();

pageContext.setAttribute("p1",p1);

p1.setName("wawa");

p1.setAge(23);

%>

<%=p1.getName()%><br/>

<%=p1.getAge()%>

 

Application配置参数

<%@ page import="java.sql.*" %>

<%

String driver = application.getInitParameter("driver");

String url = application.getInitParameter("url");

String user = application.getInitParameter("user");

String pass = application.getInitParameter("pass");

Class.forName(driver);

Connection conn = DriverManager.getConnection(url,uer,pass);

Statement stmt = conn.createStatement();

ResuletSet rs = stmt.excuteQuery("select * from news_inf");

%>

<table>

<%

while(rs.next())

{

%>

<tr>

<td><%=rs.getString(1)%></td>

<td><%=rs.getString(2)%></td>

</tr>

<%

}

%>

 

WEB-INF\web.xml

<content-param>

<param-name>driver</param-name>

<param-value>com.mysql.jdbc.Driver</param-value>

</content-param>

<content-param>

<param-name>url</param-name>

<param-value>jdbc:mydql://localhost:3306/javaee</param-value>

</content-param>

<content-param>

<param-name>user</param-name>

<param-value>root</param-value>

</content-param>

<content-param>

<param-name>pass</param-name>

<param-value>1234</param-value>

</content-param>

 

config对象

<%=config.getInitParameter("name")%>

<%=config.getInitParameter("age")%>

<servlet>

<servlet-name>config</servlet-name>

<jsp-file>/configTest.jsp</jsp-file>

<init-param>

<param-name>name</param-name>

<param-value>lee</param-value>

</init-param>

<init-param>

<param-name>age</param-name>

<param-value>23</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>config</servlet-name>

<url-pattern>/config</url-pattern>

</servlet-mapping>

 

异常处理excepiton

普通的jsp脚本只执行try部分,如果捕捉到异常则会forwarderrorPage属性指定的页面,异常处理页面负责catch异常处理段。在异常处理页面中只有isErrorPage属性设置为true才可访问exception内置对象。见[错误页面]

 

get处理非西欧字符

<%

String rawQueryStr = request.getQueryString();

out.println("原始查询字符串为:"+rawQueryStr+"<hr/>");

String queryStr=java.net.URLDecoder.decode(rawQueryStr,"gbk");

out.println("解码后的查询字符串为:"+queryStr+"<hr/>");

String[] paramPairs = queryStr.split("&");

for(String paramPair : paramPairs)

{

out.println("每个请求参数名、值对为:"+paramPair+"<br/>");

String[] nameValue = paramPair.split("=");

out.println(nameValue[0]+"参数的值是:" nameValue[1]+"<hr/>");

}

%>

或者获取请求参数值后对请求参数值重新编码

String rawName = request.getParameter("name");

byte[] rawBytes = rawName.getBytes("ISO-8859-1");

String name = new String(rawBytes, "gb2312");

 

设置中文Cookie

<%

Cookie c = new Cookie("cnName", java.net.URLEncoder.encode("孙悟空","gbk"));

c.setMaxAge(24*3600);

response.addCookie(c);

 

Cookie[] cookies = response.getCookies();

for(Cookie cookie : coolies)

{

if(cookie.getName().equals("cnName"))

{

out.println(java.net.URLDecoder.decode(cookie.getValue()));

}

}

%>

 

 

Servlet

servlet3.0开始,配置servlet有两种方式:

  • servlet类中使用@WebServlet Annotation进行配置
  • 通过在web.xml文件中配置

@WebServlet支持的常用属性

属性

是否必需

说明

asyncSupported

指定该Servlet是否支持异步操作模式。

displayName

指定改Servlet的显示名

initParams

用于为该Servlet配置参数

loadOnStartup

用于将该Servlet配置成load-on-startupServlet

name

指定该Servlet的名称

urlPatterns/value

这两个属性的作用完全相同。都指定该Servlet处理的URL

如果打算使用Annotation来配置Servlet,有两点需要指出

  • 不要在web.xml文件的根元素<web-app…/>中指定metadata-complete="true"
  • 不要在web.xml文件中配置该Servlet

 

Servlet在web.xml中配置

<servlet>

<servlet-name>firstServlet</servlet-name>

<servlet-class>lee.FirstServlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>firstServlet</servlet-name>

<url-pattern>/aa</url-pattern>

</servlet-mapping>

 

JSP/Servlet生命周期

  1. 创建Servlet实例。
  2. Web容器调用Servletinit方法,对Servlet进行初始化。
  3. Servlet初始化后,将一直存在于容器中,用于响应客户端的请求。如果客户端发送GET请求,容器调用ServletdoGet方法处理并响应请求;如果客户端发送POST请求,容器调用ServletdoPost方法处理并响应请求。或者统一使用service()方法处理来响应用户请求。
  4. Web容器决定销毁Servlet时,先调用Servletdestroy方法,通常在关闭Web应用之时销毁Servlet

 

load-on-startupServlet

创建Servlet实例有两个时机:用户请求之时或应用启动之时。应用启动时创建Servlet,通常是用于某些后台服务的Servlet,或者需要拦截很多请求的Servlet;这种Servlet通常作为应用的基础Servlet使用,提供重要的后台服务。

有两种配置方式:

  • web.xml文件中通过<servlet.../>元素的<load-on-startup…/>子元素进行配置。
  • 通过@WebServlet AnnotationloadOnStartup属性指定。

接收一个整型值,越小越先实例化。

@WebServlet(loasOnStartup=1)

public class TimerServlet extends HttpServlet

{

public void init(ServletConfig config) throws ServletException

{

super.init(config);

Timer t = new Timer(1000, new ActionListener()

{

public void actionPerformed(ActionEvent e)

{

System.out.println(new Date);

}

});

 

}

}

或者在web.xml中配置

<servlet>

<servlet-name>timerServlet</servlet-name>

<servlet-class>lee.TimerServlet</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

 

访问Servlet配置参数

两种方式

  • 通过@WebServletinitParams属性来指定。

@WebServlet(name="testServlet"

,urlPatterns={"/testServlet"}

,initParams={

@WebInitParam(name="driver",value="com.mysql.jdbc.Driver"),

@WebInitParam(name="url",value="jdbc:mysql://localhost:3306/javaee"),

@WebInitParam(name="user",value="root"),

@WebInitParam(name="pass",value="1234"),

})

public class TestServlet extends HttpServlet

{

public void service(HttpServletRequest request, HttpServletResponse response)

Throws ServletException, java.io.IOException

{

ServletConfig config = getServletConfig();

String driver = config.getInitParameter("driver");

...

}

...

}

  • 通过web.xml文件的<servlet…/>元素中添加<init-param…/>子元素来指定

<servlet>

<servlet-name>testServlet</servlet-name>

<servlet-class>lee.TestServlet</servlet-class>

<init-param>

<param-name>driver</param-name>

<param-value>com.mysql.jdbc.Driver</param-value>

</init-param>

<init-param>

<param-name>url</param-name>

<param-value>jdbc:mydql://localhost:3306/javaee</param-value>

</init-param>

<init-param>

<param-name>user</param-name>

<param-value>root</param-value>

</init-param>

<init-param>

<param-name>pass</param-name>

<param-value>1234</param-value>

</init-param>

</servlet>

<servlet-mapping>

<servlet-name>testServlet</servlet-name>

<url-pattern>/testServlet</url-pattern>

</servlet-mapping>

 

使用Servlet作为控制器

RequestDispacher rd;

HttpSession session = request.getSession(true);

session.setAttribute("name", username);

rd = request.getRequestDispacher("/login.jsp");

request.setAttribute("err", errMsg);

rd.forward(request, response);

 

JSP2的自定义标签

 

开发自定义标签类三步

  1. Java文件
    1. 继承javax.servlet.jsp.tagext.SimpleTagSupport
    2. 重写doTag()方法

public classs HelloWorldTag extends SimpleTagSupport

{

Public void doTag() throws JspException, IOException

{

getJspContext().getOut().write("Hello World" + new java.util.Date());

}

}

  1. TLD文件
    1. Tag Library Definition 标签库定义

<uri>http://www.crazyit.org/mytaglib</uri>

<tag>

<!--定义标签名-->

<name>helloWorld</name>

<!--定义处理类-->

<tag-class>lee.HelloWorldTag</tag-class>

<!--定义标签体为空-->

<body-content>empty</body-conteng>

</tag>

  1. 使用标签库
    1. 使用taglib指令将标签库和指定前缀关联起来
    2. 使用标签语法

<tagPrefix:tagName tagAttribute="tagValue"...>

<tagBody/>

</tagPrefix:tagName>

或者

<tagPrefix:tagName tagAttribute="tagValue"…/>

 

<%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%>

<mytag:helloWorld/>

 

带属性的标签

  1. java中添加属性、setget方法

private String driver;

...

  1. tld文件中配置

<body-content>empty</body-conteng>

<attribute>

<name>driver</name>

<required>true</required>

<fragment>true</fragment>

</attribute>

  1. 使用标签时,配置属性值

<mytag:query

driver="com.mysql.jdbc.Driver"

...

/>

 

带标签体的标签

通常完成一些逻辑运算,如判断和循环等

  1. doTag先重page范围内获取了指定名称的Collection对象,然后遍历Collection对象的元素,每次遍历都调用了getJspBody()方法来返回该标签所包含的标签体:JspFragment对象,执行该对象的invoke()方法,即可输出标签体的内容。

public class IteratorTag extends SimpleTagSupport

{

private String collection;

private String item;

//..getter setter方法

public void doTag() throws JspException,IOException

{

Collection itemList = (Collection)getJspContext().getAttribute(collection);

for (Object s : itemList)

{

getJspContext().setAttribute(item, s );

getJspBody().invoke(null);

}

}

}

  1. 指定标签体可以是静态HTML内容,也可以是表达式语言,但不能是jsp脚本

<body-content>sriptless</body-content>

  1. 实现遍历

<table border="1" bgcolor="#aaaadd" width="300">

<mytag:iterator collection="a" item="item">

<tr>

<td>${pageScope.item}</td>

</tr>

</mytag:iterator>

</table>

 

页面片段作为属性的标签

  1. 标签处理类中定义类型为JspFragment的属性,该属性代表“页面片段”

public class FragmentTag extends SimpleTagSupport

{

private JspFragment fragment;

//..getter setter方法

@Override

public void doTag() throws JspException,IOException

{

JspWriter out = getJspContext().getOut();

out.println("<div style='padding:10px;border:1px solid black'>");

out.println("<h3>下面是动态传入的jsp片段</h3>>");

fragment.invoke(null);

out.println("</div>");

}

}

  1. 配置tld文件

<tag>

<name>fragment</name>

<tag-class>lee.FragmentTag</tag-class>

<body-content>empty</body-conteng>

<attribute>

<name>fragment</name>

<required>true</required>

<fragment>true</fragment>

</attribute>

</tag>

  1. 使用

<mytag:fragment>

<jsp:attribute name="fragment">

<mytag:helloWorld/>

</jsp:attribute>

</mytag:fragment>

<mytag:fragment>

<jsp:attribute name="fragment">

${pageContext.request.remoteAddr}

</jsp:attribute>

</mytag:fragment>

 

动态属性的标签

属性个数,属性名都不确定

  1. 还需要实现DynamicAttributes接口

public class FragmentTag extends SimpleTagSupport implements DynamicAttributes

{

private ArrayList<String> keys = new ArrayList<String>();

private ArrayList<Object> values = new ArrayList<Object>();

@Override

public void doTag() throws JspException,IOException

{

JspWriter out = getJspContext().getOut();

out.println("<ol>");

for( int I = 0;  i<keys.size(); i++ )

{

String key = keys.get(i);

Object value = values.get(i);

out.println("<li>"+key+"="+value+"</li>");

out.println("</ol>")

}

}

@Override

public void setDynamicAttribute(String uri, String localName, Object value)

Throws JspException

{

keys.add(localName);

values.add(value);

}

}

  1. 额外指定<dynamic-attributes>子元素

<tag>

<name>dynaAttr</name>

<tag-class>lee.DynaAttributesTag</tag-class>

<body-content>empty</body-conteng>

<dynamic-attributes>true</dynamic-attributes>

</tag>

  1. 使用

<mytag:dynaAttr name="crazyit" url="crazyit.org"/></br>

<mytag:dynaAttr 书名="疯狂Java" 价格="99.0" 出版时间="2013" 描述="Java图书"/>

 

Filter

Filter可认为是Servlet的一种“加强版”,主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。

使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

Filter有如下几个用处

  • HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest
  • 根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
  • HttpServletResponse到达客户端之前,拦截HttpServletResponse
  • 根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。

Filter有如下几个种类

  • 用户授权的FilterFilter负责检查用户的请求,根据请求过滤用户非法请求。
  • 日志Filter:详细记录某些特殊的用户请求。
  • 负责解码的Filter:包括对非标准编码的请求编码。
  • 能改变XML内容的XSLT Filter等。
  • Filter可负责拦截多个请求或响应;一个请求或响应也可被多个Filter拦截。

创建一个Filter只需两个步骤:

  1. 创建Filter处理类。
  2. web.xml文件中配置Filter

 

LogFilter例子

  1. LogFilter.java

@WebFilter(filterName="log"

,urlPatterns={"/*"})

public class LogFilter implements Filter

{

private FilterConfig config;

public void init(FilterConfig config)

{

this.config = config;

}

public void destroy()

{

this.config = null;

}

public void doFilter(ServletRequest request,

ServletResponse response, FilterChain chain)

throws IOException, ServletException

{

ServletContext context = this.config.getServletContext();

long before = System.currentTimeMillis();

System.out.println("开始过滤..");

HttpServletRequest hrequest = (HttpServletRequset)request;

System.out.println("Filter已经截获到用户的请求地址:"+

hrequest.getServletPath());

chain.doFilter(request, reponse);

long after = System.currentTimeMillis();

System.out.println("过滤结束...");

System.out.println("请求被定位到:"+hrequest.getRequestURI() +

 "所花的时间为:" + (after-before))

}

}

  1. web.xml

<filter>

<filter-name>log</filter-name>

<filter-class>lee.LogFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>log</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

设置编码和验证是否登录Filter例子

  1. AuthorityFilter.java

@WebFilter(filterName="authority"

, urlPatterns="/*"

, initParams={

@WebInitParam(name="encoding", value="GBK"),

@WebInitParam(name="loginPage", value="/login.jsp"),

@WebInitParam(name="proLogin", value="/proLogin.jsp")})

public class AnthorityFilter implements Fileter

{

private FilterConfig config;

public void init(FilterConfig config)

{

this.config = config;

}

public void destroy()

{

this.config = null;

}

public void doFilter(ServletRequest request,

ServletResponse response, FilterChain chain)

throws IOException, ServletException

{

String encoding = config.getInitParameter("encoding");

String encoding = config.getInitParameter("loginPage");

String encoding = config.getInitParameter("proLogin");

request.setCharacterEncoding(encoding);

HttpServletRequest requ = ( HttpServletRequest )request;

HttpSession session  = requ.getSession(true);

if( session.getAttribute("user") == null

&& !requestPath.endsWith(loginPage)

&&!requestPath.endsWith(proLogin)

{

request.setAttribute("tip", "您还没有登录");

request.getRequestDispather(loginPage).forward(request,response);

}

ese

{

chain.doFilter(request, response);

}

}

}

 

  1. 如果在web.xml配置如下

<filter>

<filter-name>authority</filter-name>

<filter-class>lee.AuthorityFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>GBK</param-value>

</init-param>

<init-param>

<param-name>loginPage</param-name>

<param-value>/login.jsp</param-value>

</init-param>

<init-param>

<param-name>proLogin</param-name>

<param-value>/proLogin</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>authority</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

 

filter应用例子

  1. 登录http://www.tuckey.org/urlrewrite/ 站点下载Url Rewrite的最新版本
  2. 下载URL Rewrite应下载其src(urlrewritefilter-3.2.0-src.zip),解压得到
    • api:文档
    • libURL Rewrite项目编译运行所需的第三方类库
    • manual:该路径下存放了URL Rewrite项目使用手册
    • src:源代码
    • webapp:示例应用
    • LICENSE.txt等杂项文档

例子:

  1. 配置web.xml

<filter>

<filter-name>UrlRewriterFilter</filter-name>

<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>

</filter>

<filter-mapping>

<filter-name>UrlRewriteFilter</filter-name>

<url-pattern>/*</url-pattern>

</filter-mappint>

  1. WEB-INF路径下增加urlrewrite.xml,该文件定义了伪静态映射规则。

该规则是:所有发向/userinf-(\w*).html 的请求都会被forwarduser.jsp页面,并将(\w*)正则表达式所匹配的内容作为username参数值。

<urlrewrite>

<rule>

<form>/userinf-(\w*).html</form>

<to type="forward">/userinf.jsp?username=$1</to>

</rule>

</urlrewrite>

  1. 使用user.jsp页面

<%

String user = request.getParameter("username");

%>

<head>

<title><%=user%>的个人信息</title>

</head>

<body>

<%

out.println("现在时间是:" + new java.util.Data() + "<br/>");

out.println("用户名:" + user);

%>

</body>

 

Listener

使用Listener步骤:

  1. 定义Listener实现类
  2. 通过Annotation或在web.xml文件中配置Listener
    1. 使用Annotation时通常无须指定任何属性
    2. 使用web.xml配置

<listener>

<listener-class>lee.RequestListener</listener-class>

</listener>

 

常用的Web时间监听器接口

  • ServletContextListener 监听Web应用的启动和关闭
  • ServletContextAttributeListener 监听application范围属性改变
  • ServletRequestListener 监听Request
  • ServletRequestAttributeListener 监听request范围属性改变
  • HttpSessionListener 监听session
  • HttpSessionAttributeListener 监听session范围属性改变

 

Listener例子:

RequestListener.java

@WebListener

public class RequestListener

implements ServletRequestListener, ServletRequestAttributeListener

{

public void requestInitialized(ServletRequestEvent sre)

{

HttpServletRequest request = (HttpServletRequest)sre.getServletRequest();

System.out.println("---发向" + request.getRequestURI() + "请求被初始化---");

}

public void requestDestroyed(ServletRequestEvent sre)

{

HttpServletRequest request = (HttpServletRequest)sre.getServletRequest();

System.out.println("---发向" + request.getRequestURI() + "请求被初销毁---");

 

}

public void attributeAdded(ServletRequestAttributeEvent event)

{

ServletRequest request = event.getServletRequest();

String name = event.getName();

Object value = event.getValue();

System.out.println(request + "范围内添加了名为" + name + "值为" + value + "的属性");

}

public void attributeRemoved(ServletRequestAttributeEvent event)

{

ServletRequest request = event.getServletRequest();

String name = event.getName();

Object value = event.getValue();

System.out.println(request + "范围内移除了名为" + name + "值为" + value + "的属性");

}

public void attributeReplaced(ServletRequestAttributeEvent event)

{

ServletRequest request = event.getServletRequest();

String name = event.getName();

Object value = event.getValue();

System.out.println(request + "范围内替换了名为" + name + "值为" + value + "的属性");

}

}

 

JSP2特性

 

配置JSP属性

JSP属性定义使用<jsp-property-group/>元素配置,主要包括

  • 是否使用表达式语言:使用<el-ignored/>元素确定,默认false,即允许使用表达式语言。
  • 是否允许使用JSP脚本:使用<scripting-invalid/>元素确定,默认false,即允许使用JSP脚本。
  • 声明JSP页面的编码:使用<page-encoding/>元素确定,配置该元素后,可以代替每个页面page指令contentType属性的charset部分。
  • 使用隐式包含:使用<include-prelude/><include-coda/>元素确定,可以代替每个页面里使用include编译指令来包含其他页面。

 

WEB-INF\web.xml

<?xml version="1.0" encodin="GBK">

<web-app xmlns=….>

<jsp-config>

<jsp-property-group>

<!--对那些文件应用配置-->

<url-pattern>/noscript/*</url-pattern>

<!--忽略表达式语言-->

<el-ignored>true</el-ignored>

<!--页面编码的字符集-->

<page-encoding>GBK</page-encoding>

<!--不允许使用Java脚本-->

<scripting-invalid>true</scripting-invalid>

<!--隐式导入页面头-->

<include-prelude>/inc/top.jspf</include-prelude>

<!--隐式导入页面尾-->

<include-coda>/inc/bottom.jspf</include-coda>

</jsp-property-group>

<jsp-property-group>

<url-pattern>*.jsp</url-pattern>

<el-ignored>false</el-ignored>

<page-encoding>GBK</page-encoding>

<scripting-invalid>false</scripting-invalid>

</jsp-property-group>

<jsp-property-group>

<url-pattern>/inc/*</url-pattern>

<el-ignored>false</el-ignored>

<page-encoding>GBK</page-encoding>

<scripting-invalid>true</scripting-invalid>

</jsp-property-group>

</jsp-config>

</web-app>

 

EL

参见链接

 

TagFile支持

TagFile是自定义标签的简化用法,使用Tag File可以无须定义标签处理类和标签库文件,但仍然可以在JSP页面中使用自定义标签。

例子:建立一个迭代器标签

  1. 建立Tag文件WEB-INF\tags\iterator.tag

TagFile的命名:iterator.tagiterator就是标签名,后缀必须是tag

<%@ tag pageEncoding="GBK" import="java.util.List"%>

<!--定义4个标签属性-->

<%@ attribute name="bgcolor"%>

<%@ attribute name="cellcolor"%>

<%@ attribute name="title"%>

<%@ attribute name="bean"%>

<table border="1" bgcolor="$bgcolor">

<tr>

<td><b>${title}</b></td>

</tr>

<!--取出request范围的a集合-->

<%List<String> list = (List<String>)

request.getAttribute("a");

for (Object ele : list ){%>

<tr>

<td bgcolor="${cellColor}">

<%=ele%>

</td>

</tr>

<%}%>

</table>

  1. 使用

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>

<%@ page import="java.util.*"%>

<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>

<!DOCTYPE html …. >

<html xmlns="...">

<head>

<title>迭代器 tag file </title>

</head>

<body>

<h2>迭代器 tag file </h2>

<%

List<String> a  = new ArrayList<String>();

a.add("hello");

a.add("world");

a.add("java");

request.setAttribute("a", a);

%>

<tags:iterator bgColor="#99dd99" cellColor="#9999cc"

title="迭代器标签" bean="a" />

</body>

</html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值