美文网首页
Servlet与JSP学习笔记(五) JSP核心(下)

Servlet与JSP学习笔记(五) JSP核心(下)

作者: Toconscience | 来源:发表于2017-04-11 23:41 被阅读46次

同样可以参考菜鸟笔记

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" />

直观是直观,可以搞两种表示宝宝记不住啊!

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>出现的顺序。

相关文章

网友评论

      本文标题: Servlet与JSP学习笔记(五) JSP核心(下)

      本文链接:https://www.haomeiwen.com/subject/fzdpattx.html