Java Web06:JSP


JSP(Java Server Pages),Java服务器端页面,和Servlet一样用于开发动态Web

区别:

  • Servlet只能用out.write("")的方式输出页面
  • JSP就像是写HTML一样,而且还可以嵌入Java代码,为用户提供动态数据

JSP原理

在IDEA中使用Tomcat,其工作目录为C:\users\username\AppData\Local\JetBrains\IntelliJIdea2021.3\tomcat

浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet,JSP最终也会被转换为一个Java程序

JSP继承了HttpJspBase类,而该类继承了HttpServlet,所以JSP本质还是实现了Servlet接口,通过out.write("")的方式输出页面

/**
 * 初始化
 */
public void _jspInit() {}

/**
 * 销毁
 */
public void _jspDestroy() {}

/**
 * JSPService方法
 */
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException {
    
    /**
     * 判断请求类型
     */
    if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
    	final java.lang.String _jspx_method = request.getMethod();
        if ("OPTIONS".equals(_jspx_method)) {
        	response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
        	return;
      	}
        if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method){
            response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
            response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
            return;
        }
	}     

    /**
     * 内置对象,可以在JSP文件中直接调用
     */ 
    final javax.servlet.jsp.PageContext pageContext;  // 页面上下文
    javax.servlet.http.HttpSession session = null;    // 会话
    final javax.servlet.ServletContext application;   // 应用(ServletContext)
    final javax.servlet.ServletConfig config;         // 配置(ServletConfig)
    javax.servlet.jsp.JspWriter out = null;           // 输出
    final java.lang.Object page = this;               // 当前页
    HttpServletRequest request                        // 请求
    HttpServletResponse response                      // 响应

    /**
     * 输出JSP页面(除了这部分的out输出,其他地方一模一样)
     */ 
    try {
      response.setContentType("text/html; charset=utf-8");
      pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("");
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try {
            if (response.isCommitted()) {
              out.flush();
            } else {
              out.clearBuffer();
            }
          } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else throw new ServletException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
}

JSP语法和指令

Maven导入依赖


    
    
    
        javax.servlet
        javax.servlet-api
        4.0.1
    

    
    
    
        javax.servlet.jsp
        jsp-api
        2.2
    

    
    
    
        javax.servlet.jsp.jstl
        jstl-api
        1.2
    

    
    
    
        taglibs
        standard
        1.1.2
    

基本语法

<%%>、<%=%>、<%!%>、${}

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


    Title



<%--
    HTML代码会被out对象直接输出到前端
--%>

<%--
    Java代码
    写在<%%>标签中,会原封不动的输出在_jsp.java文件中,作用域为_jspService()方法
--%>
<%
    String name = "ty";

    int sum = 0;

    for (int i = 1; i <= 100; i++) {
        sum += i;
    }

    out.println("

sum = " + sum + "

"); /** * 先存入域空间才能用EL表达式读取 */ pageContext.setAttribute("name", name); %> <%-- JSP表达式 写在<%=%>标签中,将程序的输出,输出到客户端 本质是调用JspWriter的out默认对象进行输出,会在服务端被解析为Java代码然后输出,只要页面定义了name这个变量就可以访问到 --%> name:<%=name%> <%-- EL表达式(代替JSP表达式) 写在${}中,但要先在域空间存入 EL表达式的本质是从4个域空间取值,因此一定要先将name存入page域空间才能读取 --%> name:${name} <%-- JSP申明 写在<%!%>标签中,作用域为整个jsp.java类 --%> <%! static { System.out.println("全局作用域"); } %>

基本指令

<%@ page ... %>

contentType、errorPage(可在web.xml中统一配置)、import

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


<%@ page errorPage="error/error500.jsp" %>


    Title



<%
    int a = 10 / 0;
%>


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


    Title



500





        500
        /error/error500.jsp
    

    
        404
        /error/error404.jsp
    

<%@ include file="..." %>

网站公用的部分可以调用同一个JSP文件(和标签有些许区别)

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



    Title



<%--
    JSP指令
    后台会将该JSP文件的语句直接合并,用out输出
--%>
<%@ include file="common/header.jsp"%>

这是网站的主体部分

<%@ include file="common/footer.jsp"%> <%-- JSP标签 后台会调用这个JSP文件,拼接成一个页面 灵活性更高,可以定义相同的变量,作用域独立 --%>

JSP内置对象和作用域

pageContextrequest、response、sessionapplication、out、config、page、exception

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


    Title



<%

    /**
     * 这四个内置对象都可以存储数据,但是作用域不同
     * setAttribute()方法的第三个参数scope也可以手动指定作用域,但不建议
     */
    pageContext.setAttribute("name1", "pageContext");  // 保存的数据在当前页面中有效,其他页面无法获取
    request.setAttribute("name2", "request");          // 保存的数据在当前请求中有效,如果请求转发也会有效,直到请求结束
    session.setAttribute("name3", "session");          // 保存的数据在当前会话中有效,直到关闭浏览器
    application.setAttribute("name4", "application");  // 保存的数据在服务器中有效,直到关闭服务器
%>



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


    Title



<%

    /**
     * findAttribute()方法查找属性
     * 其他页面只能获取到name3和name4
     */
    String name1 = (String) pageContext.findAttribute("name1");
    String name2 = (String) pageContext.findAttribute("name2");
    String name3 = (String) pageContext.findAttribute("name3");
    String name4 = (String) pageContext.findAttribute("name4");
    String name5 = (String) pageContext.findAttribute("name5");
%>

<%--
    EL表达式
    对于不存在的name5属性,不会输出
--%>

${name1}

${name2}

${name3}

${name4}

${name5}


<%-- JSP表达式 对于不存在的属性,会输出null --%>

<%=name5%>

JSP标签、JSTL标签、EL表达式

JSP标签:http://java.sun.com/jsp/jstl/core"%>

JSTL标签库的使用是为了弥补HTML标签的不足,它定义了许多标签,功能和Java代码一样

所需依赖包:jstl-api、standard

if、out、choose、whe、forEach

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

<%--要先引入JSTL核心标签库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>



    Title



<%-- ${param.属性}获取表单的属性值 --%>
<%--if判断--%> <%--out输出--%>

JavaBean

JavaBean是Java中一种特殊的类,必须要有无参构造器,属性必须要私有化,必须使用getter()和setter()方法访问属性

作用:和JSP页面交互数据

实体类

该Java类统称为实体类,和数据库中的表结构一一对应,即数据库做对象关系映射(ORM)

package com;

public class JavaBean {

    private int id;
    private String name;
    private int age;
    private String address;

    public JavaBean(){}

    public JavaBean(int id, String name, int age, String address){

        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "com.JavaBean{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                '}';
    }
}

useBean标签

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.JavaBean" %>



    Title



<%--实例化对象people--%>


<%--赋值--%>





<%--获取值--%>
序号:
姓名:
年龄:
地址: