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部分,如果捕捉到异常则会forward到errorPage属性指定的页面,异常处理页面负责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-startup的Servlet |
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生命周期
- 创建Servlet实例。
- Web容器调用Servlet的init方法,对Servlet进行初始化。
- Servlet初始化后,将一直存在于容器中,用于响应客户端的请求。如果客户端发送GET请求,容器调用Servlet的doGet方法处理并响应请求;如果客户端发送POST请求,容器调用Servlet的doPost方法处理并响应请求。或者统一使用service()方法处理来响应用户请求。
- Web容器决定销毁Servlet时,先调用Servlet的destroy方法,通常在关闭Web应用之时销毁Servlet。
load-on-startupServlet
创建Servlet实例有两个时机:用户请求之时或应用启动之时。应用启动时创建Servlet,通常是用于某些后台服务的Servlet,或者需要拦截很多请求的Servlet;这种Servlet通常作为应用的基础Servlet使用,提供重要的后台服务。
有两种配置方式:
- 在web.xml文件中通过<servlet.../>元素的<load-on-startup…/>子元素进行配置。
- 通过@WebServlet Annotation的loadOnStartup属性指定。
接收一个整型值,越小越先实例化。
@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配置参数
两种方式
- 通过@WebServlet的initParams属性来指定。
@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的自定义标签
开发自定义标签类三步
- Java文件
- 继承javax.servlet.jsp.tagext.SimpleTagSupport
- 重写doTag()方法
public classs HelloWorldTag extends SimpleTagSupport { Public void doTag() throws JspException, IOException { getJspContext().getOut().write("Hello World" + new java.util.Date()); } } |
- TLD文件
- 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> |
- 使用标签库
- 使用taglib指令将标签库和指定前缀关联起来
- 使用标签语法
<tagPrefix:tagName tagAttribute="tagValue"...>
<tagBody/>
</tagPrefix:tagName>
或者
<tagPrefix:tagName tagAttribute="tagValue"…/>
<%@ taglib uri="http://www.crazyit.org/mytaglib" prefix="mytag"%> … <mytag:helloWorld/> |
带属性的标签
- java中添加属性、setget方法
private String driver; ... |
- tld文件中配置
… <body-content>empty</body-conteng> <attribute> <name>driver</name> <required>true</required> <fragment>true</fragment> </attribute> … |
- 使用标签时,配置属性值
<mytag:query driver="com.mysql.jdbc.Driver" ... /> |
带标签体的标签
通常完成一些逻辑运算,如判断和循环等
- 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); } } } |
- 指定标签体可以是静态HTML内容,也可以是表达式语言,但不能是jsp脚本
<body-content>sriptless</body-content> |
- 实现遍历
<table border="1" bgcolor="#aaaadd" width="300"> <mytag:iterator collection="a" item="item"> <tr> <td>${pageScope.item}</td> </tr> </mytag:iterator> </table> |
页面片段作为属性的标签
- 标签处理类中定义类型为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>"); } } |
- 配置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> |
- 使用
<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> |
动态属性的标签
属性个数,属性名都不确定
- 还需要实现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); } } |
- 额外指定<dynamic-attributes>子元素
<tag> <name>dynaAttr</name> <tag-class>lee.DynaAttributesTag</tag-class> <body-content>empty</body-conteng> <dynamic-attributes>true</dynamic-attributes> </tag> |
- 使用
<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有如下几个种类
- 用户授权的Filter:Filter负责检查用户的请求,根据请求过滤用户非法请求。
- 日志Filter:详细记录某些特殊的用户请求。
- 负责解码的Filter:包括对非标准编码的请求编码。
- 能改变XML内容的XSLT Filter等。
- Filter可负责拦截多个请求或响应;一个请求或响应也可被多个Filter拦截。
创建一个Filter只需两个步骤:
- 创建Filter处理类。
- web.xml文件中配置Filter。
LogFilter例子
- 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)) } } |
- 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例子
- 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); } } } |
- 如果在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应用例子
- 登录http://www.tuckey.org/urlrewrite/ 站点下载Url Rewrite的最新版本
- 下载URL Rewrite应下载其src项(urlrewritefilter-3.2.0-src.zip),解压得到
- api:文档
- lib:URL Rewrite项目编译运行所需的第三方类库
- manual:该路径下存放了URL Rewrite项目使用手册
- src:源代码
- webapp:示例应用
- LICENSE.txt等杂项文档
例子:
- 配置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> |
- 在WEB-INF路径下增加urlrewrite.xml,该文件定义了伪静态映射规则。
该规则是:所有发向/userinf-(\w*).html 的请求都会被forward到user.jsp页面,并将(\w*)正则表达式所匹配的内容作为username参数值。
… <urlrewrite> <rule> <form>/userinf-(\w*).html</form> <to type="forward">/userinf.jsp?username=$1</to> </rule> </urlrewrite> |
- 使用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步骤:
- 定义Listener实现类
- 通过Annotation或在web.xml文件中配置Listener
- 使用Annotation时通常无须指定任何属性
- 使用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页面中使用自定义标签。
例子:建立一个迭代器标签
- 建立Tag文件WEB-INF\tags\iterator.tag
TagFile的命名:iterator.tag中iterator就是标签名,后缀必须是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> |
- 使用
<%@ 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> |