同样可以参考菜鸟笔记。
JSP标签
JSP除了包括以"<%"开头的JSP标记,还包括以"<jsp:"开头的JSP标签。实际上,前者的每种标记都有后者的替代。例如:
- Java程序片段又可以写成:
<jsp:scriptlet>代码片段</jsp:scriptlet>
- JSP声明又可以写成:
<jsp:declaration>代码片段</jsp:declaration>
- JSP表达式又可以写成:
<jsp:expression>JAVA表达式</jsp:expression>
- 甚至JSP指令都被JSP标签替代了:
- Page指令:
<jsp:directive.page attribute="value" />
- Include指令:
<jsp:directive.include file="相对url地址" />
- Taglib指令:
<jsp:directive.taglib uri="uri" prefix="prefixOfTag" />
- Page指令:
直观是直观,可以搞两种表示宝宝记不住啊!
JSP动作元素
JSP动作元素就是一组以"<jsp:"开头的JSP标签,在请求处理阶段起作用,可以动态地做一些事情。下面是标准的动作元素:
语法 | 描述 |
---|---|
jsp:include | 在页面被请求的时候引入一个文件。 |
jsp:useBean | 寻找或者实例化一个JavaBean。 |
jsp:setProperty | 设置JavaBean的属性。 |
jsp:getProperty | 输出某个JavaBean的属性。 |
jsp:forward | 把请求转到一个新的页面。 |
jsp:plugin | 根据浏览器类型为Java插件生成OBJECT或EMBED标记。 |
jsp:element | 定义动态XML元素 |
jsp:attribute | 设置动态定义的XML元素属性。 |
jsp:body | 设置动态定义的XML元素内容。 |
jsp:text | 在JSP页面和文档中使用写入文本的模板 |
具体的解释在下面讲解。
包含
也许你会注意到,前面介绍了JSP指令中的Include指令,表示包含一个文件;后面的JSP动作元素又有一个jsp:include动作,这两者有什么区别?区别就是,Include指令用于静态包含,而include标签用于动态包含。
- 静态包含:在编译源JSP时,把包含的目标文件的所有内容融合进来,然后编译JSP文件。
- 动态包含:把
<jsp:include
指令编译成JspRuntimeLibrary.include(request, response, "target.jsp", ...)
。执行到这个方法时,再去编译target.jsp,把它编译成独立的Servlet类,然后调用它的service()方法。最后再继续执行源文件的后续代码。
示例:主JSP文件代码如下:
main.jsp is including content.jsp.
<% int var=1;
request.setAttribute("username","Tom");
%>
<%@ include file="content.jsp" %>
<p>main.jsp is doing something else.
content.jsp文件:
<p>
Output from content.jsp:
<br>
var=<%=var %>
<br>
username=<%=request.getAttribute("username") %>
访问main.jsp会有正常的响应。如果改为动态包含,则浏览器会显示异常:content.jsp的编译有问题,因为var
没有被定义。
访问JavaBean
JavaBean我的理解就是一种domain class,特点是有个无参构造函数,以及每个属性都有get和set方法封装。JSP中使用Bean,就可以使HTML与Java代码分离,让JavaBean负责事务处理,可以分离界面与业务,也能够重用业务代码。
下面是一个标准的Bean:
package com.runoob.main;
public class TestBean {
private String message = "菜鸟教程";
public String getMessage() {
return(message);
}
public void setMessage(String message) {
this.message = message;
}
}
JSP中操作Bean主要用到三个动作元素:
-
<jsp:useBean>
. 通过id属性指定变量名,class属性指定Bean的类名,scope属性指定JavaBean对象的存放范围(可选page(默认)、request、session、application)。
这行代码:<jsp:useBean id="test" class="com.runoob.main.TestBean" />
实际的处理流程如下:- 定义一个名为test的局部变量。
- 尝试从默认的page范围内读取名为"test"的属性,并赋给test。
- 如果"test"属性不存在,就通过TestBean类的默认构造方法创建一个对象,并把它存放在page范围内,属性名为"test"。
也就是等价于以下代码:
TestBean test = null; test = (TestBean) pageContext.getAttribute("test"); if (test == null) { test = new TestBean(); pageContext.setAttribute("test", test); }
-
<jsp:getProperty>
和<jsp:setProperty>
. 通过前面的id来定位Bean。
最后用一个示例来说明用法:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Bean示例</title>
</head>
<body>
<h2>Jsp 使用 JavaBean 实例</h2>
<jsp:useBean id="test" class="com.runoob.main.TestBean" />
<jsp:setProperty name="test"
property="message"
value="菜鸟教程..." />
<p>输出信息....</p>
<jsp:getProperty name="test" property="message" />
</body>
</html>
过滤器
Web组件常常会做一些相同的工作。比如都要检查客户的IP地址是否在黑名单中。过滤器(Filter)就是为了解决重复编写相同操作代码而产生的,可以实现以下目的:
- 在客户端的请求访问后端资源之前,拦截这些请求。
- 在服务器的响应发送回客户端之前,处理这些响应。
过滤器接口javax.servlet.Filter定义了三个方法:
方法 | 描述 |
---|---|
void doFilter (ServletRequest, ServletResponse, FilterChain) | 完成实际的过滤操作。FilterChain用于访问后续过滤器或Web组件。 |
void init(FilterConfig filterConfig) | Web应用程序启动时,容器会创建Filter的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能。 |
void destroy() | Servlet容器在销毁过滤器实例前调用该方法,释放其占用的资源。 |
下面是一个IP过滤器的示例:
package mypack;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class IPFilter implements Filter {
public void init(FilterConfig config) throws ServletException {}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 如果客户IP在黑名单里,就直接返回拒绝信息,不再调用后续组件
if (!checkRemoteIP(request, response)) {
return;
}
// 把请求转发给后续组件
chain.doFilter(requestWrapper, response);
}
public void destroy() {}
private boolean checkRemoteIP(ServletRequest request, ServletResponse response) {
String addr = request.getRemoteAddr();
if (addr.indexOf(ipblock) == 0) {
response.setContentType("text/html;charset=UTF8");
PrintWriter out = response.getWriter();
out.println("<h1>对不起,你的IP地址有毒!</h1>");
out.flush();
return false;
}
return true;
}
}
过滤器在web.xml中的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<filter>
<filter-name>IPFilter</filter-name>
<filter-class>mypack.IPFilter</filter-class>
<init-param>
<param-name>Site</param-name>
<param-value>参数值</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>IPFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
...
也可以配置多个过滤器。如果它们指向的url一致,就是串联的关系,串联顺序就是<filter-mapping>出现的顺序。
网友评论