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

同样可以参考菜鸟笔记。

JSP标签

JSP除了包括以"<%"开头的JSP标记,还包括以"

  • Java程序片段又可以写成:代码片段
  • JSP声明又可以写成:代码片段
  • JSP表达式又可以写成:JAVA表达式
  • 甚至JSP指令都被JSP标签替代了:
    • Page指令:
    • Include指令:
    • Taglib指令:

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

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文件。
  • 动态包含:把指令编译成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" %> 

main.jsp is doing something else.

content.jsp文件:

Output from content.jsp:
var=<%=var %>
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主要用到三个动作元素:

  • . 通过id属性指定变量名,class属性指定Bean的类名,scope属性指定JavaBean对象的存放范围(可选page(默认)、request、session、application)。
    这行代码: 实际的处理流程如下:

    • 定义一个名为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);
    }
    
  • . 通过前面的id来定位Bean。

最后用一个示例来说明用法:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Bean示例



Jsp 使用 JavaBean 实例

输出信息....

过滤器

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

对不起,你的IP地址有毒!

"); out.flush(); return false; } return true; } }

过滤器在web.xml中的配置如下:

  
  

  IPFilter
  mypack.IPFilter
  
    Site
    参数值
  


  IPFilter
  /*

...

也可以配置多个过滤器。如果它们指向的url一致,就是串联的关系,串联顺序就是出现的顺序。

你可能感兴趣的:(Servlet与JSP学习笔记(五) JSP核心(下))