文章目录

  • 一 JSP
  • 1.1 jsp介绍
  • 1.2 jsp相关概念
  • 1.3 jsp脚本
  • 1.3.1 普通脚本
  • 1.3.2 声明脚本
  • 1.3.3 输出脚本
  • 1.4 jsp注释
  • 1.5 jsp指令
  • 1.5.1 include指令(了解)
  • 1.5.2 page指令
  • 1.5.3 taglib指令
  • 1.6 jsp内置对象
  • 1.7 jsp中四大域对象
  • 1.7.1 pageContext域对象
  • 二 el表达式
  • 2.1 el表达式介绍
  • 2.2 el获取域数据基本使用
  • 2.3 el获取复杂域数据
  • 2.4 el表达式执行运算
  • 2.5 el表达式中web对象
  • 三 jstl标签库
  • 3.1 介绍
  • 3.1.1 环境准备
  • 3.2 jstl核心标签
  • 3.2.1 set标签
  • 3.2.2 remove标签
  • 3.2.3 catch标签
  • 3.2.4 if标签
  • 3.2.5 forEach标签
  • 3.2.6 forToken标签
  • 3.2.7 choose标签
  • 3.2.8 ul标签
  • 3.3 jstl综合案例——显示商品信息
  • 3.3.1 准备工作
  • 3.3.2 功能完成
  • 四 jsp模式
  • 4.1 model1模式
  • 4.2 model2模式
  • 五 BeanUtils框架
  • 5.1 开发步骤
  • 5.2 自定义BeanUtils框架
  • 六 mvc设计模式


一 JSP

1.1 jsp介绍
为什么要引入jsp?
  	 html文件无法获取java程序中的数据,同时,如果使用Servlet来显示java数据又显得不太合理!
  	综上,需要一门技术,既可以显示页面,同时也可以获取java程序中的数据

什么是jsp
 	 jsp:java server page
  	简单理解为,它就是一个可以获取java数据的html文件。
1.2 jsp相关概念
jsp为什么是一个Servlet
  	jsp文件会转义成对应的java文件
  	比如:demo01.jsp转义成demo01_jsp.java,类demo01_jsp会继承于HttpJspPage,HttpJspPage又是Servlet子类,demo01.jsp就是Servlet
  	
jsp的执行流程
  	浏览器发起请求demo01.jsp
  	demo01.jsp就会转义生成对应demo01_jsp.java
  	在demo01_jsp类中,通过JspWriter类将demo01.jsp中的html标签作为响应正文响应给浏览器进行渲染显示!
1.3 jsp脚本
作用
	可以在页面上写java代码

分类
 	声明脚本:<%! java代码 %>	在jsp对应java类中,生成一个成员变量
  	片段脚本:<% java代码 %>	在jsp对应的java类的_jspService方法中,生成一个局部变量
  	输出脚本::<%= 变量值 %>	向浏览器输出内容,相当于response.getWriter().write()
1.3.1 普通脚本

<% java代码%>

Hello World!<br/>
  <%
    //jsp使用小脚本嵌入代码
    out.println("hi");
    System.out.println("hello");
  %>
  • 普通脚本可以使用所有java语法,除了定义函数
  • 脚步与脚本之间不可嵌套,脚步与html标签不可嵌套
1.3.2 声明脚本

<%! 定义变量、函数%>

<%! int i=0;%>
  <%! int a,b,c;%>
  <%! Object object = new Object();%>
  <%!
    //定义方法
    public void m1(){
      System.out.println("你好");
    }
  %>
  • 声明脚本声明的变量是全局变量
  • 声明脚本的内容必须在偶同脚本中调用
  • 如果声明脚本中的函数具有返回值,可以使用输出脚本调用<%= %>
1.3.3 输出脚本

<%= java表达式%>

<p>
      今天的日期是:<%=new java.util.Date()%>
    </p>

输出脚本可以输出带有返回值的函数
输出脚本没有“;”

1.4 jsp注释
jsp文件中,既可以有html代码,也可以有java代码
这就意味着,jsp文件中,既可以使用html注释,也可以使用java注释,同时还可以使用jsp注释
html注释	<!-- -->
	用来注释html代码
	会将注释内容生成到jsp对应的java文件中
	通过浏览器查看源代码可以看见
java注释	//
	用来注释java代码
	会将注释内容生成到jsp对应的java文件中
jsp注释	<%--  --%>
	用来注释html代码
	不会讲注释内容生成到jsp对应的java文件中
	注释内容不会发送至浏览器甚至不会被编译
<p>
      今天的日期是:<%=new java.util.Date()%>
    </p>
  <%--jsp注释在网页中不会被显示--%>
  <!--html注释在网页中会显示-->
1.5 jsp指令

用于指示jsp执行某些操作 、用于指示jsp表现特定行为或效果

<%@ 指令名称 属性名1="属性值1" 属性名2="属性值2" %>
1.5.1 include指令(了解)

用于将外部引入到jsp文件中

<%@ include file="top.jsp"%>
1.5.2 page指令
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" errorPage="error.jsp" %>
<%@ page isErrorPage="true" %>
contentType="text/html;charset=UTF-8"
	告诉浏览器应该以utf-8解码响应正文,告诉服务器应该以utf-8对响应正文进行编码

language="java"
  	设置jsp页面能够使用的语言,不动!

import="java.util.List" 
  	在当前jsp页面中导入List类

isELIgnored="false"
  	当前jsp页面不要忽略el表达式,默认就是不忽略

errorPage="error.jsp"
  	当前jsp页面发生异常,所要跳转到页面

isErrorPage="true"
  	标记当前jsp页面是否是一个错误页面,如果为true那么就可以使用jsp内置对象exception,否则不能使用
1.5.3 taglib指令

在当前jsp页面中导入jstl标签库

<%@taglib prefix="前缀" uri="路径" %>
  • 导入jstl标签库
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
1.6 jsp内置对象

可以在jsp页面上直接使用的对象

内置对象名

描述

page

当前页面对象

java.lang.Object

pageContext

当前页面上下文对

javax.servlet.jsp.PageContext

request

请求对象

javax.servlet.http.HttpServletRequest

response

响应对象

javax.servlet.http.HttpServletResponse

session

会话对象

javax.servlet.http.HttpSession

config

ServletConfig对象

javax.servlet.ServletConfig

exception

异常对象

java.lang.Throwable

application

ServletContext对象

javax.servlet.ServletContext

out

JspWriter对象

javax.servlet.jsp.JspWriter

在jsp对应的java文件中,已经提前声明好了这些内置对象,所以可以直接使用

  • request、response、session
<%
//    String username = request.getParameter("username");
//    System.out.println(username);
//    response.getWriter().write(username);
//    session.setAttribute("msg","hello jsp");
    application.setAttribute("msg","hello jsp jsp");
%>
<%
//    String msg = (String) session.getAttribute("msg");
//    System.out.println(msg);
    String msg = (String) application.getAttribute("msg");
    System.out.println(msg);
%>
<%
    out.write("i am very happy");
%>
1.7 jsp中四大域对象

域对象:就是可以用来存储数据对象

jsp域对象
	request	代表整个请求链
	
  	session	整个会话
  	
  	application	整个web应用
  	
  	pageContext	代表page域,但是jsp中page它的类型是Object,所以操作page域我们使用的是
  				pageContext对象,page域就是指当前页面范围
1.7.1 pageContext域对象
作用
  	获取其他的内置对象
  	
  	操作域
    	操作page域
    	操作request、session、application
  • 获取其他的内置对象
  • 没有获取out内置对象
<%
      pageContext.getPage();//获取内置对象page
      pageContext.getRequest();//获取内置对象request
      pageContext.getResponse();//获取内置对象response
      pageContext.getSession();//获取内置对象session
      pageContext.getServletContext();//获取application
      pageContext.getServletConfig();//config
      pageContext.getException();//exception
  %>
  • 操作page域
  • 作用范围只在当前页面
<%
        //往pageContext域中存储了一个msg变量
        pageContext.setAttribute("msg" ,"hello page msg");
    %>
    
    <%
        //往pageContext域中存储了一个msg变量
        Object msg = pageContext.getAttribute("msg");
        System.out.println(msg);
    %>
  • 操作其他域
  • request域
<%
        //定义变量的意义! 提高复用性! 提高可维护性!
        //String name : 参数名称
        //Object value : 参数值
        //int scope : 操作的域
        pageContext.setAttribute("msg1","hello page1",PageContext.REQUEST_SCOPE);
        //请求转发
        request.getRequestDispatcher("/demo06.jsp").forward(request,response);
    %>
    
    <%
        //变量msg1定义到_jspService方法中
        Object msg1 = request.getAttribute("msg1");
        System.out.println("msg1 : "+msg1);
    
        Object msg11 = pageContext.getAttribute("msg1", PageContext.REQUEST_SCOPE);
        System.out.println(msg11);
    %>
  • session域
<%
        pageContext.setAttribute("msg2","hello page2",PageContext.SESSION_SCOPE);
    %>
  • application域
<%
        pageContext.setAttribute("msg3","hello page3",PageContext.APPLICATION_SCOPE);
    %>

二 el表达式

2.1 el表达式介绍

el(expression language),是由jsp内置提供
el表达式用来替换jsp脚本

作用
  	向页面输出数据
  	获取web对象
格式	
	${表达式}

如果page指令中isELIgnored=“true”,jsp页面就不会解析执行el表达式,会原样显示

2.2 el获取域数据基本使用
  • 获取page域数据
<%
  pageContext.setAttribute("msg1","hello page1");
  %>
  
  ${pageScope.msg1}
  • 获取request域数据
<%
  request.setAttribute("msg1","hello page1");
  %>
  
  ${requestScope.msg1}
  • 获取session域数据
<%
  session.setAttribute("msg1","hello page1");
  %>
  
  ${sessionScope.msg1}
  • 获取application域数据
<%
  application.setAttribute("msg1","hello page1");
  %>
  
  ${applicationScope.msg1}
2.3 el获取复杂域数据
  • 获取数组
<%
      //数组静态初始化
      String[] msgs = {"tom","steve","barry"};
      pageContext.setAttribute("msgs",msgs);
  %>
  <%--jsp输出脚本--%>
  <%=
      ((String[])pageContext.getAttribute("msgs"))[0]
  %>
  ${msgs[1]}
  • 获取List集合
<%
      List<String> msgs1 = new ArrayList<>();
      msgs1.add("kate");
      msgs1.add("jay");
      request.setAttribute("msgs1",msgs1);
  %>
  
  <%=
      ((List<String>)request.getAttribute("msgs1")).get(0)
  %>
  
  ${msgs1[1]}
  • 获取map集合
<%
      HashMap<String,Object> map = new HashMap<>();
      map.put("username","jerry");
      map.put("age",16);
      session.setAttribute("map",map);
  %>
  
  <%=
      ((HashMap<String,Object>)session.getAttribute("map")).get("username")
  %>
  ${map.age}
  • 获取java对象
<%
      User user = new User();
      user.setId(1);
      user.setUsername("alex");
      user.setPassword("123456");
      application.setAttribute("user",user);
  %>
  <%=
      ((User)application.getAttribute("user")).getUsername()
  %>
  
  ${user.password}
2.4 el表达式执行运算
  • 算术运算
+
  -
  *
  /:div
  %:mod
  • 关系运算
> : gt
  >= : ge
  < : lt
  <= : le
  == : eq
  != : ne
  • 逻辑运算
&& : and
  || : or
  !  : not
  • 三元运算
${num1 gt num2 ? "num1大于num2" : "num1不大于num2"}
2.5 el表达式中web对象
  • 11个web对象

el表达式

说明

pageScope

(常用)

是page域对象,获取pageContext域属性

requestScope

(常用)

获取request域属性

sessionScope

(常用)

获取session域属性

applicationScope

(常用)

获取application域属性

param

对应参数,它是一个Map,其中key是参数,value是参数值,适用于单值的参数

相当于request.getParameter()

paramValues

对应参数,她是一个Map,其中key是参数,value是多个参数值,适用于多值的参数

相当于request.getParameterValues()

header

对应请求头,它是一个Map,其中key表示头名称,value是单个头值,适用于单值的请求头

获取单个请求头值

headerValues

对应请求头,它是一个Map,其中key表示头名称,value是多个头值,适用于多值的请求头

获取一组请求头的值

initParam

获取初始化参数,获取web.xml中内的参数

cookie

(常用)

用于获取cookie

Map<String,Cookie>,其中key是cookie的name,value是cookie对象

pageContext

(常用)

相当于pageContext对象,获取jsp九大内置对象

应用场景:获取当前项目路径
	${pageContext.request.contextPath}

三 jstl标签库

3.1 介绍

jstl (java standard tag libarary),jsp标签库,它是apache对el表达式的扩展
和el表达式结合使用,可以让功能更加强

3.1.1 环境准备
  • 导入jar包
  • 在jsp页面导入jstl标签库
  • 使用taglib指令
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
3.2 jstl核心标签
3.2.1 set标签

向域对象(page域、request域、session域、application域)中存储数据

var:参数名称
scope:域
value:参数值
<c:set var="msg" scope="request" value="hello jstl"></c:set>
  ${msg}
3.2.2 remove标签

移除域对象中的数据

var:参数名称
scope:域
<c:remove var="msg" scope="request"></c:remove>
  ${msg}<br>
3.2.3 catch标签

捕获jsp页面的异常,相当于try…catch

var:声明异常对象名称,比如:var="e" ,变量e就可以接收异常对象
<c:catch var="e">
      <%
          int num = 1 / 0;
      %>
  </c:catch>
  ${e}<br>
3.2.4 if标签

条件判断

test :编写条件
<c:set var="num" value="2" scope="request"></c:set>
  <c:if test="${num == 1}">
      num 等于 1
  </c:if>
  
  <c:if test="${num != 1}">
      num 不等于 1
  </c:if>
3.2.5 forEach标签

遍历集合或数组

begin:开始
end:结束
step:步数
var:元素名称
items:集合/数组
varStatus:元素状态对象
	first:是否是第一个元素
	last:是否是最后一个元素
	current:当前元素
	index“:当前脚标
<!-- 基本使用 -->
  <c:forEach begin="1" end="10" step="3" var="num">
      ${num}
  </c:forEach>
  
  <%
      List<String> strs  = new ArrayList<>();
      strs.add("aaa");
      strs.add("bbb");
      strs.add("ccc");
      request.setAttribute("strs",strs);
  %>
  <!-- 相当于普通for循环 -->
  <c:forEach begin="0" end="${strs.size() - 1}" step="1" var="i">
      ${strs[i]}
  </c:forEach>
  
  <!-- 相当于增强for循环 -->
  <c:forEach var="str" items="${strs}" varStatus="status">
  	${str}<br>
      ${status.current} -- ${status.index} -- ${status.first} -- ${status.last}<br>
  </c:forEach>
3.2.6 forToken标签

分割字符串

items:要分割的字符串
delims:分割的规则
var:分割产生的元素
<%
      String msg1 = "aaa--bbb--ccc";
      request.setAttribute("msg1",msg1);
  %>
  
  <c:forTokens items="${msg1}" delims="--" var="sonMsg">
      ${sonMsg}
  </c:forTokens>
3.2.7 choose标签

<c:choose>标签与switch语句功能一样,用于在众多选项中做出选择

<c:choose>
	<c:when test="条件1">结果1</c:when>
	<c:when test="条件2">结果2</c:when>
	<c:when test="条件3">结果3</c:when>
	<c:otherwise>结果4</c:otherwise>
</c:choose>
3.2.8 ul标签

<c:ul>标签将URL格式化为一个字符串,然后存储在变量中
自动重写URL,var属性用于存储格式化后的URL

<c:ul value='${pageContext.request.contextPath}/xxxController' var="myurl"/>
3.3 jstl综合案例——显示商品信息
3.3.1 准备工作
  • 导入jar包
  • java 设计网页 java语言网页设计_java 设计网页

  • ProductDao
public class ProductDaoImpl implements ProductDao {
      @Override
      public List<Product> selectProductList() throws Exception {
          return new QueryRunner(JDBCUtils.getDataSource())
                  .query("select * from tb_product",
                          new BeanListHandler<Product>(Product.class));
      }
   }
  • ProductServlet
@WebServlet(name = "ProductServlet" ,urlPatterns = "/selectProductList")
  public class ProductServlet extends HttpServlet {
  
      protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          ProductDao productDao = new ProductDaoImpl();
          try {
              List<Product> productList = productDao.selectProductList();
              System.out.println(productList);
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
  
      protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
          doPost(request, response);
      }
  }
3.3.2 功能完成
  • productList.jsp
<table border="1px" cellspacing="0px" cellpadding="10px" width="500px" height="200px">
      <tr>
          <td>ID</td>
          <td>名称</td>
          <td>单价</td>
          <td>数量</td>
          <td>小计</td>
      </tr>
      <%--循环之前,总价为0--%>
      <c:set var="total" value="0" scope="page"></c:set>
      <c:forEach items="${productList}" var="product">
          <%--forEach标签,循环一次就是一个小计!--%>
          <tr>
              <td>${product.id}</td>
              <td>${product.name}</td>
              <td>${product.price}</td>
              <td>${product.count}</td>
              <td>${product.price * product.count}</td>
          </tr>
          <c:set var="total" value="${total + product.price * product.count}" scope="page"></c:set>
      </c:forEach>
      <%--循环之后,计算出总价--%>
      <tr>
          <td colspan="5" align="right">
              总价:${total}元
          </td>
      </tr>
  
  </table>

四 jsp模式

分类
	model1模式	jsp+javaBean
	model2模式	jsp+javaBean+Servlet
4.1 model1模式

java 设计网页 java语言网页设计_数据_02

jsp
    处理请求
    业务处理
    操作数据库
    显示数据

javaBean
    封装数据
优点:开发简单
缺点:维护难,代码几乎都在jsp中
<%@ page import="org.apache.commons.dbutils.QueryRunner" %>
<%@ page import="util.JDBCUtils" %>
<%@ page import="org.apache.commons.dbutils.handlers.BeanListHandler" %>
<%@ page import="bean.Product" %>
<%@ page import="java.util.List" %>
<%@ page import="java.security.interfaces.RSAKey" %><%--
  Created by IntelliJ IDEA.
  User: EVA_01
  Date: 2020/4/28 0028
  Time: 15:13
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>jsp的model1模式</title>
</head>
<body>
<%
    //请求处理
    //业务处理
    //操作数据库
    List<Product> productList = new QueryRunner(JDBCUtils.getDataSource())
            .query("select * from tb_product", new BeanListHandler<Product>(Product.class));
    System.out.println(productList);
    pageContext.setAttribute("productList",productList);
//    request.getRequestDispatcher("/productList1.jsp").forward(request, response);
%>

<table border="1px" cellspacing="0px" cellpadding="10px" width="500px" height="200px">
    <tr>
        <td>ID</td>
        <td>名称</td>
        <td>单价</td>
        <td>数量</td>
        <td>小计</td>
    </tr>
    <%--循环之前,总价为0--%>
    <c:set var="total" value="0" scope="page"></c:set>
    <c:forEach items="${productList}" var="product">
        <%--forEach标签,循环一次就是一个小计!--%>
        <tr>
            <td>${product.id}</td>
            <td>${product.name}</td>
            <td>${product.price}</td>
            <td>${product.count}</td>
            <td>${product.price * product.count}</td>
        </tr>
        <c:set var="total" value="${total + product.price * product.count}" scope="page"></c:set>
    </c:forEach>
    <%--循环之后,计算出总价--%>
    <tr>
        <td colspan="5" align="right">
            总价:${total}元
        </td>
    </tr>

</table>
</body>
</html>
4.2 model2模式

java 设计网页 java语言网页设计_el表达式_03

servlet
    处理请求
    业务处理
    操作数据库

jsp
    显示数据

javaBean
    封装数据
优缺点
	维护方便,开发人员各司其职,有利于我们进行分工操作
	比较适合开发一些比较复杂项目,因为它的很多组件可以重用。
	开发难度增大,对开发人员要求比较高

五 BeanUtils框架

可以将请求参数封装到java对象中

5.1 开发步骤
  • 导包
Map<String, String[]> map = request.getParameterMap();
        User user = new User();
        System.out.println(user);
        try {
            BeanUtils.populate(user,map);
            System.out.println(user);
        } catch (Exception e) {
            e.printStackTrace();
        }

页面上的name属性值要和java对象中的属性名一致

5.2 自定义BeanUtils框架
  • MyBeanUtils
public class MyBeanUtils {  
      /**
       * 将map集合中的请求参数值封装到对象t中
       * @param t
       * @param map : 键:参数名称;值:一组参数值。
       * @param <T>
       */
      public static<T> void populate(T t , Map<String,? extends Object> map ){
          Class<?> clazz = t.getClass();
          Field[] fields = clazz.getDeclaredFields();
          for (Field field : fields) {
              String fieldName = field.getName();
              String methodName = "set"+fieldName.substring(0,1).toUpperCase()+fieldName.substring(1);
              System.out.println(methodName);
              //获取对应的set方法
              try {
                  Class<?> type = field.getType();
                  Method method = clazz.getMethod(methodName, type);
                  if (null != method) {
                      //第二个参数:请求参数的值
                      //id、username、password、age
                      Object object = map.get(fieldName);
                      if (null != object) {
                          String[] strs = (String[]) object;
                          if (type.getName().equals("java.lang.Integer")) {
                              method.invoke(t,Integer.parseInt(strs[0]));
                          } else {
                              method.invoke(t,strs[0]);
                          }
                      }
                  }
              } catch (Exception e) {
  //                e.printStackTrace();
                  throw new MyNoSuchMethodException("field " + fieldName + " there is no setter method!!!");
              }
          }
  
      }
  
  }
  • MyNoSuchMethodException
public class MyNoSuchMethodException extends RuntimeException{
  
      public MyNoSuchMethodException() {
      }
  
      public MyNoSuchMethodException(String message) {
          super(message);
      }
  
      public MyNoSuchMethodException(String message, Throwable cause) {
          super(message, cause);
      }
  
      public MyNoSuchMethodException(Throwable cause) {
          super(cause);
      }
  
      public MyNoSuchMethodException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
          super(message, cause, enableSuppression, writableStackTrace);
      }
  }


六 mvc设计模式

它是一种软件设计典范,用一种业务逻辑,数据,界面分离的方式来组织代码,将业务逻辑聚集 到一个部件中,方便程序的重复使用,提高我们的开发效率


jsp的model2模式是mvc设计模式的一种

  • 业务分工
m:	model	数据封装
v:	view	显示页面,即视图层 数据的显示 jsp
c:	controller	控制层,用于业务处理,而业务处理包含:处理请求、业务逻辑、操作数据库
存在的弊端
    c中的代码太多,职责不单一!需要使用到三层结构
  • 三层结构
web层:处理请求
service层:业务逻辑,业务层
dao层:操作数据库,持久层