JSP知识随手记

目录

介绍

  JSP全称是Java Server Pages,它和Servlet技术一样,都是SUN公司定义的一种用于开发动态Web页面(资源)的技术。
  JSP技术允许在页面中编写Java代码,并且允许开发人员在页面中获取request、response等Web开发常用对象,实现与浏览器的交互,所以JSP也是一种动态Web资源的开发技术。

JSP运行原理

  每个JSP页面在第一次被访问时,Web容器都会把请求交给JSP引擎(即一个Java程序)去处理。JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个Servlet),然后按照Servlet的调用方式进行调用。(翻译后的Servlet保存在Tomcat的work目录,如:H:\MySoftware\Tomcat\apache-tomcat-9.0.0.M4\work\Catalina\localhost\JavaWeb\org\apache\jsp
  由于JSP第一次访问时会翻译成Servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所有程序的执行效率不会受到影响。

JSP最佳实践

  不管是JSP还是Servlet,虽然都可以用于开发动态Web资源。但由于这两门技术各自的特点,在长期的软件实践中,人们逐渐把Servlet作为Web应用中的控制器组件来使用,而把JSP技术作为数据显示模板来使用。
  根据这两门技术的特点,让它们各自负责各的,Servlet只负责响应请求产生数据,并把数据通过转发技术带给JSP,由JSP来进行数据的显示。

JSP指令

page指令

  1. JSP中Page指令的errorPage属性用于设置JSP页面出错时显示的页面内容,errorPage属性的设置值必须使用相对路径,如果以“/”开头,表示相对于当前Web应用程序的根目录(注意不是站点根目录)。
  2. 可以在web.xml文件中使用<error-page>元素为整个Web应用程序设置错误处理页面,其中的<exception-type>子元素指定异常的完全限定名,<location>元素指定以“/”开头的错误处理页面的路径。如:
<error-page>
    <exception-type>java.lang.ArithmeticException</exception-type>
    <location>/errors/error.jsp</location>
</error-page>

 
3. 如果设置了某个页面的Page指令的errorPage属性,那么在web.xml文件中设置的错误处理将不对该页面起作用。
4. 服务器抛404时显示的页面设置:(在web.xml中设置)

<error-page>
    <error-code>404</error-code>
    <location>/errors/404.jsp</location>
</error-page>

include指令

  include指令,通过该指令可以在一个JSP页面中包含另一个JSP页面。不过该指令是静态包含,也就是说被包含文件中所有内容会被原样包含到该JSP页面中,即使被包含文件中有JSP代码,在包含时也不会被编译执行。
include指令为静态包含(编译时包含),它包含的所有JSP页面都只会同原来的JSP页面编译成一个servlet。语法:

<%@ include file="relativeURL"%>

  其中的file属性用于指定被引入文件的路径。路径以“/”开头,表示代表当前Web应用。
  被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理JSP页面的方式处理它里面的内容,为了见名知意,JSP规范建议使用.jspf(JSP fragments)作为静态引入文件的扩展名。
  被引入的JSP页面的指令不能冲突(除了pageEncoding和导包除外)。
  
  示例:
index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/public/header.jsp"%>
<h4>页面主体内容...</h4>
<%
    // 注释
    out.write("测试中文输出");
%>
<%@ include file="/public/footer.jsp"%>

被包含页面:header.jsp、footer.jsp(这里以.jspf后缀更好)
header.jsp

<%@ page import="java.util.Date" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Header</title>
</head>
<body>
<p><%=new Date().toLocaleString()%></p>

footer.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<p>这是页脚</p>
</body>
</html>

  动态包含(运行时包含):包含过程中,所涉及到的所有JSP页面都将对应单独编译成一个servlet。
  示例:
  index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    request.getRequestDispatcher("/public/header.jsp").include(request, response);
%>
<h4>页面主体内容...</h4>
<%
    // 注释
    response.getWriter().write("测试中文输出");
%>
<%
    request.getRequestDispatcher("/public/footer.jsp").include(request, response);
%>

  此外,静态包含比动态包含的效率要好。

taglib指令

  taglib指令,用于在JSP页面中导入标签库。

JSP九大内置对象

  JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与Web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些Web对象的引用,特意定义了9个相应变量。
  JSP中的内置对象 request、response、session、application、config、page、exception、out、pageContext。

out隐式对象

  • out隐式对象用于向客户端发送文本数据。
  • out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。
  • JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至关闭它的缓存。
  • 只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
    • 设置page指令的buffer属性关闭out对象的缓存功能;
    • out对象的缓冲区满;
    • 整个JSP页面结束

pageContext隐式对象

  pageContext对象,代表JSP页面的运行环境,封装了对其他8大隐式对象的引用。

getException方法 返回exception隐式对象
getPage方法 返回page隐式对象
getRequest方法 返回request隐式对象
getResponse方法 返回response隐式对象
getServletConfig方法 返回config隐式对象
getServletContext方法 返回application隐式对象
getSession方法 返回session隐式对象
getOut方法 返回out隐式对象

  pageContext对象也是一个域对象(拥有getAttribute和setAttribute方法),作用于页面范围,即page域,不同页面不能共享pageContext中存储的数据。
  pageContext对象中包含findAttribute方法,用于查找各个域中的属性。findAttribute方法的查找顺序为page域(PageContext对象)、request域、session域、application域(ServletContext对象)。(由小到大)如:

<%
    pageContext.findAttribute("data");
%>

  相当于EL表达式中的

${data}

  pageContext还拥有forward和include方法用来分别简化和替代RequestDispatcher.forward方法和include方法。方法接收的参数为资源的路径,如果以“/”开头,“/”代表当前Web应用。

JSP标签

  JSP标签也称之为Jsp Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能,避免在JSP页面中直接编写Java代码,造成JSP页面难以维护。
  JSP常用标签:
- <jsp:include>标签

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

  相当于(属于动态包含)

pageContext.include("/1.jsp");
  • <jsp:forward>标签
<jsp:forward page="/1.jsp"></jsp:forward>
  • <jsp:param>标签
      示例:
      param.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>JSP常用标签</title>
</head>
<body>
    <jsp:forward page="/ServletDemo1">
        <jsp:param name="username" value="DreamBoy"/>
        <jsp:param name="password" value="123456"/>
    </jsp:forward>
</body>
</html>

  ServletDemo1.java

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * Created by DreamBoy on 2017/5/9.
 */
@WebServlet(name = "ServletDemo1", urlPatterns = {"/ServletDemo1"})
public class ServletDemo1 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }
}

映射JSP

  在web.xml中配置jsp页面映射的URL路径(别忘了访问JSP实际上就是访问JSP编译后的Servlet):

    <servlet>
        <servlet-name>ServletDemo1</servlet-name>
        <jsp-file>/index.jsp</jsp-file>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletDemo1</servlet-name>
        <url-pattern>/index.html</url-pattern>
    </serlvet-mapping>

知识点

  1. JSP说白了就是Servlet。运行过程中服务器会将JSP编译对应的Servlet。
  2. JSP中的内置对象 request、response、session、application、config、page、exception、out、pageContext。
  3. JSP页面中编写的所有代码,默认会翻译到Servlet的service方法中,而JSP声明中Java代码被翻译到_jspService方法的外面。语法为:
<%!
    // Java代码
%>

  JSP声明可用于定义JSP页面转换成Servlet程序的静态代码块、成员变量和方法。
  多个静态代码块、变量和函数可以定义在一个JSP声明中,也可以分别单独定义在多个JSP声明中。
  我们可以理解为在Servlet中定义了一些属性。
4. JSP隐式对象的作用范围仅限于Servlet的_jspService方法,所以在JSP声明中不能使用这些隐式对象(JSP九大内置对象)

JSP与JavaBean

  JavaBean是一个遵循特定写法的Java类,它通常具有如下特点:
- 该Java类必须具有一个无参的构造函数
- 属性必须私有化
- 私有化的属性提供public访问权限的get、set方法暴露给其他程序
  JavaBean的属性可以是任意类型,并且一个JavaBean可以有多个属性。每个属性通常都需要具有相应的gettersetter方法。其中getter方法称为属性访问器;setter方法称为属性修改器。
  一个JavaBean的某个属性也可以只有set方法或get方法,这样的属性通常也称之为只写、只读属性。
  示例:
Person.java

package com.wm103.domain;
import java.util.Date;
/**
 * Created by DreamBoy on 2017/5/9.
 */
public class Person {
    private String name;
    private int age;

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    private Date birthday;
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

关于JavaBean的JSP标签

  • <jsp:useBean>标签:用于在指定的域范围内(默认page域,即pageContext)查找指定名称的JavaBean对象。如果存在则直接返回该JavaBean对象的引用。如果不存在则实例化一个新的JavaBean对象并将它以指定的名称存储到指定的域范围中。
<jsp:useBean id="person" class="com.wm103.domain.Person" scope="page"></jsp:useBean>

  其中scope属性的取值只能为page、request、session和application等四个值中的一个,其默认值是page。

  • <jsp:setProperty>标签:用于在JSP页面中设置一个JavaBean组件的属性。
  • <jsp:getProperty>标签:用于在JSP页面中获取一个JavaBean组件的属性。
    读取JavaBean对象的属性,也就是调用JavaBean对象的getter方法,然后将读取的属性值转换成字符串后插入进输出的相应正文中。
    如果一个JavaBean实例对象的某个属性的值为null,那么,使用<jsp:getProperty>标签输出该属性的结果将是一个内容为“null”的字符串。
      示例:
<%--
  Created by IntelliJ IDEA.
  User: DreamBoy
  Date: 2017/5/9
  Time: 10:46
  To change this template use File | Settings | File Templates.
--%>
<%@ page import="java.util.Date" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>jsp:setProperty标签的使用</title>
</head>
<body>
    <p>
        请求
        <pre>
            http://localhost:8080/day09/2.jsp?name=xiaoxiao&age=18
        </pre>
    </p>

    <jsp:useBean id="person" class="com.wm103.domain.Person"/>

    <!-- 手工为bean属性赋值 -->
    <jsp:setProperty name="person" property="name" value="DreamBoy"/>
    <h4>手工为bean属性赋值</h4>
    <p><%=person.getName()%></p>

    <!-- 用请求参数给bean属性赋值 -->
    <jsp:setProperty name="person" property="name" param="name"/>
    <jsp:setProperty name="person" property="age" param="age"/> <!-- 支持8种基本数据类型的转换(把客户机提交的字符串,转成相应的8种基本数据类型,赋值到bean的属性上 -->
    <jsp:setProperty name="person" property="birthday" value="<%=new Date()%>"/>
    <h4>用请求参数给bean属性赋值</h4>
    <p><%=person.getName()%></p>
    <p><%=person.getAge()%></p>
    <p><%=person.getBirthday()%></p>

    <!-- 用所有的请求参数为bean赋值 -->
    <jsp:setProperty name="person" property="*"/>
    <h4>用所有的请求参数为bean赋值</h4>
    <p><%=person.getName()%></p>
    <p><%=person.getAge()%></p>

    <!-- 获取bean的属性 -->
    <jsp:getProperty name="person" property="name"/>
    <jsp:getProperty name="person" property="age"/>
</body>
</html>

JSP+JavaBean开发模式

  实现计算器案例:
  JavaBean CalculatorBean.java

package com.wm103.domain;

/**
 * Created by DreamBoy on 2017/5/9.
 */

import java.math.BigDecimal;

/**
 * 封装计算器数据的Bean
 */
public class CalculatorBean {
    private String firstNum;
    private char operator;
    private String secondNum;
    private String result;

    public String getFirstNum() {
        return firstNum;
    }

    public void setFirstNum(String firstNum) {
        this.firstNum = firstNum;
    }

    public char getOperator() {
        return operator;
    }

    public void setOperator(char operator) {
        this.operator = operator;
    }

    public String getSecondNum() {
        return secondNum;
    }

    public void setSecondNum(String secondNum) {
        this.secondNum = secondNum;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public void calculate() {
        if(this.firstNum == null || this.secondNum == null) {
            return;
        }

        BigDecimal first = new BigDecimal(this.firstNum);
        BigDecimal second = new BigDecimal(this.secondNum);
        switch (this.operator) {
            case '+':
                this.result = first.add(second).toString();
                break;
            case '-':
                this.result = first.subtract(second).toString();
                break;
            case '*':
                this.result = first.multiply(second).toString();
                break;
            case '/':
                if(second.doubleValue() == 0) {
                    throw new RuntimeException("被除数不能为0!");
                }
                this.result = first.divide(second, 2, BigDecimal.ROUND_HALF_UP).toString();
                break;
            default:
                throw new RuntimeException("该运算符不存在!");
        }
    }
}

  calculator.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 上述3个meta标签*必须*放在最前面,任何其他内容都*必须*跟随其后! -->
    <title>计算器</title>

    <!-- Bootstrap -->
    <link href="./public/assets/bootstrap-3.3.7/css/bootstrap.min.css" rel="stylesheet">

    <!-- HTML5 shim and Respond.js for IE8 support of HTML5 elements and media queries -->
    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
    <!--[if lt IE 9]>
    <script src="https://cdn.bootcss.com/html5shiv/3.7.3/html5shiv.min.js"></script>
    <script src="https://cdn.bootcss.com/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->
</head>
<body>
<div class="container">
    <div style="padding: 50px 20px;" data-example-id="table-within-panel">
        <div class="panel panel-primary">
            <!-- Default panel contents -->
            <div class="panel-heading">
                <h3>简易计算器</h3>
            </div>

            <jsp:useBean id="calculatorBean" class="com.wm103.domain.CalculatorBean"/>
            <jsp:setProperty name="calculatorBean" property="*"/>

            <div class="panel-body">
                <%
                    try {
                        calculatorBean.calculate();
                    } catch (Exception e) {
                        out.write("<h4>" + e.getMessage() + "</h4>");
                    }
                %>

                <%
                    if (calculatorBean.getResult() != null) {
                %>
                <h3>
                    计算结果是:
                    <jsp:getProperty name="calculatorBean" property="firstNum"/>
                    <jsp:getProperty name="calculatorBean" property="operator"/>
                    <jsp:getProperty name="calculatorBean" property="secondNum"/>
                    =
                    <jsp:getProperty name="calculatorBean" property="result"/>
                </h3>
                <%
                    }
                %>
            </div>
            <form action="calculator.jsp" method="post">
                <!-- Table -->
                <table class="table table-striped table-hover">
                    <tbody>
                        <tr>
                            <th scope="row">第一个参数</th>
                            <td><input type="text" class="form-control" name="firstNum" placeholder=""></td>
                        </tr>
                        <tr>
                            <th scope="row">运算符</th>
                            <td>
                                <select name="operator" class="form-control">
                                    <option value="+">+</option>
                                    <option value="-">-</option>
                                    <option value="*">*</option>
                                    <option value="/">/</option>
                                </select>
                            </td>
                        </tr>
                        <tr>
                            <th scope="row">第二个参数</th>
                            <td>
                                <input type="text" class="form-control" name="secondNum" placeholder="">
                            </td>
                        </tr>
                        <tr>
                            <td colspan="2">
                                <button type="submit" class="btn btn-info btn-block">提交</button>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </form>
        </div>
    </div>
</div>

<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script src="./public/assets/bootstrap-3.3.7/js/bootstrap.min.js"></script>
</body>
</html>

  运行效果:
  
JSP+JavaBean模式实现简易计算器

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值