JSP详析

JSP详析

本文章适合小白,内附详细代码
小知识点:
**静态网页:**无法实现搜索、购买、登录等交互功能 无法对静态页面的内容进行实时更新
**动态网页:**可以实时和后端服务器进行交互,保证页面内容和功能的丰富多彩 网页文件里包含了程序代码,通过后台数据库与WEB服务器的信息交互,由后台数据库提供实时数据更新和数据查询服务。

B/S程序架构(浏览器和服务器结构)
JSP详析_第1张图片
JSP详析_第2张图片
B/S架构执行原理:
JSP详析_第3张图片
B/S类的程序是通过浏览器输入服务器的地址通过网络与远程的服务器进行沟通,在此过程中,
我们输入的服务器地址叫做URL;

URL(Uniform Resource Locator):统一资源定位符,即网址
URL是唯一能识别Internet上具体的计算机\目录或文件夹位置的命名约定
URL组成:
JSP详析_第4张图片
Java 连接 数据库 mysql:jdbc://127.0.0.1:3306/dbname?characterEncoding=UTF-8
当你输入URL时会发生什么1
当输入URL发生什么2

Tomcat服务器简介
Tomcat是 Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。
由于有了Sun 的参与和支持,最新的Servlet 和JSP 规范总是能在Tomcat 中得到体现,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。
因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。
对于一个初学者来说,可以这样认为,当在一台机器上配置好Apache 服务器,可利用它响应HTML(标准通用标记语言下的一个应用)页面的访问请求。
实际上Tomcat是Apache 服务器的扩展,但运行时它是独立运行的,所以当你运行tomcat 时,它实际上作为一个与Apache 独立的进程单独运行的。
诀窍是,当配置正确时,Apache 为HTML页面服务,而Tomcat 实际上运行JSP 页面和Servlet。另外,Tomcat和IIS等Web服务器一样,具有处理HTML页面的功能,另外它还是一个Servlet和JSP容器,独立的Servlet容器是Tomcat的默认模式。不过,Tomcat处理静态HTML的能力不如Apache服务器。
tomcat取官网下载解压就能使用
JSP详析_第5张图片
启动(startup.bat)和关闭(shutdown.bat)tomcat的程序在bin目录下,我们以后写的web程序是放在webapps目录下的
tomcat的运行需要依赖jre,所以你的电脑必须是安装好jre环境的,可以验证一下你电脑中是否装有jre环境
可以 cmd 窗口下输入 java -version 查看java 版本
JSP详析_第6张图片
开发web项目流程展示:
JSP详析_第7张图片

JSP(Java Server Pages)在Java中嵌入Java脚本代码

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

  
    输出当前日期
  
  
    你好,今天是
  <% SimpleDateFormat formater = new SimpleDateFormat("yyyy年 MM月 dd日");
  String strCurrentTime = formater.format(new Date()); %>
  <%=strCurrentTime %>
  

JSP是将Java代码作为脚本融入到HTML中,注意在HTML标签之间我们就可以写一些Java代码,完成我们页面的一些动态功能效果;执行原理:
JSP详析_第8张图片


JSP中的page命令

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

通过设置内部的多个属性定义整个页面的属性
JSP详析_第9张图片
常用属性:

属性 描述 默认值
language 指定JSP页面使用的脚本语言 java
import 通过该属性来引用脚本语言中使用到的类文件
contentType 用来指定JSP页面所采用的编码方式 text/html,IOS-8859-1

JSP 中的小脚本与表达式
在JSP界面中计算两个数的和,输出结果:

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




计算求和


	两个数的求和结果为:
	<%                           
		int num1 = 2,num2 = 5;   
		int result = num1 + num2;
	%>   
	<%=result %>   


如果想在HTML中编写java代码 我们必须用 <%%> 来编写Java代码,.这种编写java代码的方式叫小脚本
那么如果想展示那些变量的值的话 我们需要使用 <%=变量 %> 的形式进行展示 这种展示风格叫做表达式展示
JSP中的声明
方法声明:
语法 :<%! Java代码%>
案例:在JSP页面定义方法对日期进行格式化:

<%@page import="java.util.Date"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




对日期格式化


	<%!
	String formatDate(Date d){
		SimpleDateFormat formater = new SimpleDateFormat("yyyy年MM月dd日");
		return formater.format(d);
	}
	%>
	你好,今天是
	<%=formatDate(new Date()) %>


JSP 中的注释
JSP详析_第10张图片
JSP详析_第11张图片


JSP案例1:使用JSP技术连接MySQL完成数据库的展示

需求分析:以person数据为例,进行数据页面化效果展示
具体实现:

  1. 在src下创建应用包:top.mublog.db
  2. 导入dbutils mysql驱动 druid jar包(把jar包复制粘贴到WebContent/WEB-INF/lib目录下)
  3. 创建实体类person
package top.mublog.db;
/**
 * 人员信息实体类
 * @author Amanda
 *
 */
public class person {
	//属性
	private Integer pid ; //主键ID
	private String pname; //姓名
	private String sex;  //性别
	private Integer age;  //年龄
	private String pn;  //籍贯
	public Integer getPid() {
		return pid;
	}
	public void setPid(Integer pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getPn() {
		return pn;
	}
	public void setPn(String pn) {
		this.pn = pn;
	}
}


  1. JDBCUtil工具类编写
package top.mublog.db;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * 数据库连接
 * @author Amanda
 *
 */
public class JDBCUtil {
	
	//创建数据库连接对象
	private static final String CONN_DRIVER = "com.mysql.jdbc.Driver";
//	private static final String CONN_URL = "jdbc:mysql://127.0.0.1:3306/jdbcdb?characterEncoding=UTF-8";
	private static final String CONN_URL = "jdbc:mysql:///jdbc_db?characterEncoding = UTF-8";
	private static final String CONN_USER = "root";
	private static final String CONN_PASSWORD = "123456";
	
	//创建数据源对象
	private static DruidDataSource dataSource = new DruidDataSource();
	
	//赋值
	static{
		dataSource.setDriverClassName(CONN_DRIVER);
		dataSource.setUrl(CONN_URL);
		dataSource.setUsername(CONN_USER);
		dataSource.setPassword(CONN_PASSWORD);
	}
	
	//添加获取数据源的方法
	public static DruidDataSource getDataSource(){
		return dataSource;
	}
}

  1. 页面调用
    编写查询数据库方法,并展示数据代码:
<%@page import="org.apache.commons.dbutils.handlers.BeanListHandler"%>
<%@page import="top.mublog.db.JDBCUtil"%>
<%@page import="top.mublog.db.person"%>
<%@page import="java.util.List"%>
<%@page import="org.apache.commons.dbutils.QueryRunner"%>
<%@page import="com.mysql.jdbc.Connection"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




人员数据展示


	
		<%
			//获取数据库连接
// 			Connection conn = JDBCUtil.getConn();
			//创建SQL执行对象
			QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
			//编写SQL语句
			String sql = "SELECT * FROM PERSON";
			//占位符赋值?
			// 执行SQL语句
			List list = qr.query(sql, new BeanListHandler(person.class));
			//遍历展示
			for(person p : list){
				%>
				
				<% 
			}
			//关闭数据库连接
// 			JDBCUtil.closeConn(conn);
		%> 
	
编号姓名性别年龄籍贯
<%=p.getPid() %> <%=p.getPname() %> <%=p.getSex() %> <%=p.getAge() %> <%=p.getPn() %>

启动tomcat,浏览器运行结果:
JSP详析_第12张图片
实现分析:
JSP详析_第13张图片
JSP中结
JSP详析_第14张图片


JSP优化

JSP的内置对象
上面的案例中,页面加入Java代码,显的混乱,使用我们把一个功能分成两个终端(客户端与服务端)(前端与后端),客户端接收数据 提交给对服务端 服务端处理 后展示给客户端 -->这就是一个完整的请求/相应模式;
数据在页面间的传递,可以使用JSP内置对象解决
JSP内置对象时Web容器创建的一组对象
JSP详析_第15张图片
JSP内置对象的名称是JSP 的保留字,JSP内置对象是可以直接在JSP页面使用的对象,无需使用“new”,直接使用。那么像这样的对象一共有9个
JSP中一共预先定义了9个这样的对象,分别为:request、response、session、application、out、pagecontext、config、page、exception

  1. request对象
    request对象是javax.servlet.httpSerletRequest类型的对象.该对象代表了客户端 的请求信息,主要用于接受HTTP协议传送到服务器的数据(包括头信息、系统信息、请求方式及请求参数等)。request对象的作用域为一次请求
  2. response对象
    response 代表的是对客户端的响应,主要是将JSP容器处理过的对象传回到客户端.response对象也具有作用域,它只在JSP页面内有效
  3. session对象
    session 对象是有服务器自动创建的与用户请求相关的对象.服务器为每个用户生成一个session对象,用于保存该用户的信息,跟踪用户的操作状态.session对象内部使用Map类来保存数据,因此保存数据的格式为:“Key/value”
  4. application对象
    application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效. 与session对象相比,application对象生命周期更长,类似于系统的"全局变量".
  5. out对象
    out对象用于Web浏览器内输出信息,并且管理应用服务器上的输出缓冲区.使用out对象输出数据时,可以对数据缓冲区进行操作,及时清楚缓冲区中残余数据,为其他的输出让出缓冲空间.待数据输出完毕后,要及时关闭输出流
  6. pageContext对象
    pageContext对象的作用是取得任何范围的参数,通过它可以获取JSP页面的out、request、reponse、session、 application等对象。pageContext对象的创建和初始化都是由容器来完成的,在JSP页面中可以直接使用pageContext对象。
  7. condig对象
    config对象主要作用是取得服务器配置信息.通过pageContext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。
  8. page对象
    exception 对象的作用是显示异常信息,只有在包含 isErrorPage=“true” 的页面中才可以被使用,在一般的JSP页面中使用该对象将无法编译JSP文件。excepation对象和Java的所有对象一样,都具有系统提供的继承结构。exception 对象几乎定义了所有异常情况。在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。

request对象
==request对象主要用于处理客户端请求
JSP详析_第16张图片
实例2:传输一个HelloWorld a.jsp 有一个from表单需要往 b.jsp传入一个name="userName"的文本框内容

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




数据传送


	
please tell me your name:

b.jsp接收这个内容并展示

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

<%
	//在接收数据之前设置请求的编码
	request.setCharacterEncoding("UTF-8");
	//获取a.jsp提交的数据
	String userName = request.getParameter("userName");
	out.print("Welcom " + userName + " to the JSP's world!");
%>

注意:在接收页面数据的时候 需要根据页面 form表单中封装的 input标签的name值来进行接收
并且此处接收到的数据只能是String 类型 ,因为这是我们的数据传输协议(HTTP协议)限制的


request对象可自爱请求与响应之间进行数据传递,request常用方法有:

方法名称 说明
String getParameter(String name) 根据表单组件名称获取提交数据
String[] get Parameter Values(String name) 获取表单组件对应多个值时的请求数据
Void setCharacterEncoding(String charset) 指定每个请求的编码
RequestDispatcher getRequestDispatcher(String path) 返回一个RequestDispatcher对象,该对象的forward()方法用于转发请求

案例:
a.jsp

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




数据传送


	

Please tell me your name:

Please tell me you hobby:
看书
旅行
骑行
看电影
购物

b.jsp

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

<%
	//在接收数据之前设置请求的编码
	request.setCharacterEncoding("UTF-8");
	//获取a.jsp提交的数据
	String userName = request.getParameter("userName");
	//接收一堆name相同的复选框的值
	String[] hobby = request.getParameterValues("hobby"); //多个name,一个用String变量,多个就需要用String[] 
	out.print("Welcom " + userName + " to the JSP's world!
"); out.print("诶呀,好巧!我也喜欢" + Arrays.toString(hobby) + "!"); %>

request 还有一个方法就是 getRequestDispatcher 这个方法可以帮助request在多个页面之间跳转并且传递的数据还会被转发过程中包含的页面共享


案例2要求:

  1. 普通用用户与VIP贵宾登录的时候提交到统一的地址
  2. 服务器接收到用户姓名再判断用户身份跳转到不同页面展示
    实现这个需求我们就可以使用request对象的转发功能来实现
    实现步骤:
  1. 创建用户登录页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




用户登录页面


	

请输入您的姓名:

  1. 创建login_server.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//模拟数据库定义两组人
	//普通用户
	String[] users = {"陈玄伯","杜子美","陈叔同"};
	//VIP用户
	String[] vips = {"张仲景","尹子樵"};
	//设定编码
	request.setCharacterEncoding("UTF-8");    //tomcat8及以上get传输会自动转码,post不自动转码,所有要设置编码模式
	//接收页面请求
	String userName = request.getParameter("userName");
	//定义最终的展示结果页
	String result = "error.jsp";//默认错误页
	//哦按分段是不是普通用户
	for(String a : users){
		if(userName.equals(a)){
			result = "users.jsp";
			break;
		}
	}
	
	//判断是不是VIP用户
	for(String b : vips){
		if(userName.equals(b)){
			result = "vips.jsp";
			break;
		}
	}
	
	//根据业务结果转发到对应页面
	request.getRequestDispatcher(result).forward(request,response);   //request 内部有一个类似于map数据结构,可以在页面之间进行数据共享
%>

此处调用就是request对象的getRequestDispatcher方法,这个方法有一个参数是用来设定将请求发送的地址,页面发起请求先由统一的一个服务页面接收,然后根据业务不同再转发
给其他页面进行操作;
后面的forward()方法叫做转发方法,也就是将现在的请求处理再交给其他程序处理,里面有两个参数 request,response(后面讲解)
注意 : 转发的写法 是 先设定请求地址 getRequestDispatcher(“x.jsp”) 然后再调用转发方法 forward(request, response) 缺一不可!

  1. 创建结果展示页面
    普通用户users.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




普通用户


	
欢迎,<%=request.getParameter("userName") %>

赶紧充钱成为VIP用户

会员vips.vip

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




至尊VIP登录

  



  

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

尊贵的VIP会员
<%=request.getParameter("userName") %>
欢迎您

出错界面:error.jsp

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




诶呀,出错了


	

出错了

问题:不管是哪个展示页面其实地址栏中的地址始终停留在最开始被请求的login_server.jsp
在这里插入图片描述
地址栏中请求的地址还是停留在login_server.jsp,这就是转发特性了面对客户端来说它只知道请求传递给了login_server.jsp,然后login_server.jsp再把请求交给谁处理就是服务器内部的事情了
虽然我们不能很明确的知道内部细节,但是最终结果就是不管导了多少手,数据的传输肯定是通畅的,所以
在request内部进行这种请求转发处理的时候不管转了多少次,都是可以接收到最开始请求的数据的;
而这种数据传输处理的方式 叫做request的请求转发链 它的特点就是发生在服务器内部 浏览器看不到 每个内部的处理环节都可以处理请求的数据;

实战案例3:MVC模式与JSTL表达式
1)案例需求:页面1 发起请求希望能够展示所有人员信息 页面2接收并处理请求后转发给页面3展示数据
2)具体实现
1) 编写开始请求页面page1.jsp

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




转发案例的请求页面


	

欢迎使用人员信息管理系统

请选择一个功能吧!

  1. 查询全部人员信息

JSP详析_第17张图片
2) 编写page2来处理本次请求

<%@page import="org.apache.commons.dbutils.handlers.BeanListHandler"%>
<%@page import="top.mublog.db.person"%>
<%@page import="java.util.List"%>
<%@page import="top.mublog.db.JDBCUtil"%>
<%@page import="org.apache.commons.dbutils.QueryRunner"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//获取数据
	//编写SQL语句
	String sql = "SELECT * FROM PERSON";
	//创建SQL执行对象
	QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
	//占位符赋值
	//执行
	List persons = qr.query(sql,new BeanListHandler(person.class));
	//保存数据
	request.setAttribute("list",persons);
	//转发
	request.getRequestDispatcher("page3.jsp").forward(request, response);
%>

注:page2.jsp调用了一个request.setAttribute(key, val); 的方法 将我们自己的list集合 用 名称 persons 保存在了request对象中,
此处大家需要注意的就是 request对象不仅能够保存页面中的提交元素,其实我们自己也可以往request里放入各种各样的值

  1. page3.jsp展示数据
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>




转发案例的展示页面


	

展示人员信息

编号 姓名 性别 年龄 籍贯
${p.pid } ${p.pname } ${p.sex } ${p.age } ${p.pn }

这个数据的展示页面,完全没有java代码,但是还能展示出来数据
这个数据的展示页中我们应用一个EL表达式和JSTL表达式
JSP详析_第18张图片

案例3总结 1: MVC模式

  1. 什么是软件设计模式?
    软件设计模式(Design pattern),又称设计模式,是一套被反复使用、多人知晓的、经过分类编目的、代码设计经验总结。
    使用设计模式是为了可重用代码、让代码更容易他人理解、保证代码可靠性、程序的重用性。

  2. 什么是MVC?
    MVC(Model View Controller)是模型(model)-视图(view)-控制器(controller)的缩写,一种设计软件规范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。MVC被独特的发展起来用于映射传统的输入、处理和输出功能在一个逻辑的图形化用户界面的结构中。

视图(View)-对应组件:JSP或HTML文件

控制器(Controller)-对应组件:Serlet(光写代码的JSP)
模型(Model)-对应组件:JavaBean
JSP详析_第19张图片
MVC能够使我们的各个组件得以最大限度的复用,降低各大组件的耦合

  1. MVC的发展历程
    第一阶段:之前写的代码
    JSP详析_第20张图片
    第二阶段(接下来会介绍)
    JSP详析_第21张图片
    第三阶段:框架设计阶段
    JSP详析_第22张图片
  2. MVC设计模式的优缺点
    优点:
    多视图共享一个模型,大大提高代码的可重用性
    MVC三个模块相互独立,松耦合架构
    控制器提高了应用程序的灵活性和可配置性
    有利于软件工程化管理
    缺点:
    原理过于复杂
    增加了系统结构和实现的复杂性,难度;
    视图对模型数据的低效率访问
    5)总结
    现在我们就处在原始的model1的开发模式中 用一个JSP发送请求给 另一个jsp,接收请求的这个JSP作为控制器,完成对数据的封装(我们通过查询可以获取对象或者list)
    这就形成了模型,然后我们通过JSP内置对象转发给下一个JSP页面来展示数据,这个页面就是视图;
    当然,model1设计模式虽然好,但是在面对大型复杂业务的时候封装度还是不够,代码编写麻烦,重复率高

实例3总结 2:EL与JSTL
EL表达式:

  1. 为什么要用EL表达式
    小脚本取值对于页面来说过于繁琐,相对来说,EL表达式的形式取某个值就很轻松了

例:
小脚本:
JSP详析_第23张图片
EL表达式:
JSP详析_第24张图片
在获取某个值的时候因为不会再涉及Java代码,所以取值更灵活;

  1. EL表达式概述
    EL(Expression Language)表达式脚本语言–JSP内部一组已经定义好的获取数据的规范 ${已经存在的值}
    EL的功能:替代JSP页面中数据访问时的复杂编码
    EL的特点:自动转换类型-EL得到某个数据时可以自动转换类型,所有不管从处理什么类型数据其实都是一样的 ,使用简单
  2. EL表达式语法
${EL expression}

我们可以通过变量名取值,通过 对象.属性 的方式取值,通过集合名称获取集合元素
例:

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

${pageContext.request.contextPath}



request.setAttribute("username","admin");


姓名:${username}



request.setAttribute("p",person);

人员编号:${p.id} 人员名称:${p.name} ...


List:

List names = new ArrayList();
names.add(0,"LiYangt");
names.add(1,"WangHua");
request.setArribute("name",names);


姓名: ${name[0] }
姓名: ${name[1] }
注意:此处用 变量[索引] 的方式来获取集合中元素的值 Map: Map names = new HashMap(); names.put("one","kLiYahr"); names.put("tow","whanghua"); request.setArribute("names",names); 姓名:${names.one}
姓名:${names[tow]}
注意:其实获取map值只是把索引换成key而已
  1. EL 表达式的基本操作符
    关系操作符:
    JSP详析_第25张图片
    逻辑操作符:
    JSP详析_第26张图片
    empty操作符:若变量a文null , 或长度为零的String, 或size为零的集合则${empty a}返回的结果为TRUE
    n o t e m p t y a 或 {not empty a}或 notemptya{! empty a} 返回结果为false
  2. 总结:以后我们页面取值的话,肯定都统一使用EL表达式进行取值和值的各种判断,所以== ${参数名称} ==这种EL表达式取值一定要记住

JSTL表达式

  1. 为什么要使用JSTL?
    使用EL表达式可以简化JSP页面编码,封装了数据访问的功能,但是如果需要进行逻辑判断和循环控制EL表达式是办不到的,而JSTL标签库整合弥补了这一问题;
    JSTL标签库则封装了逻辑控制、循环控制以及数据格式化等功能,二者结合使用才能完整实现动态页面的开发需求;

  2. 什么是JSTL?
    JSTL(JavaServer Pages Standard Tag Library)-JSP标准标签库-是一个不断完善的开放源代码的JSP标签库,是由apache的jakarta小组来维护的。
    JSTL的优点是提供一组标准标签,可用于编写各种动态功能;

  3. 怎么用JSTL
    1>引入jar包
    jstl.jar : jstl标签的核心jar包
    standard.jar : JSP标准标签库
    2>导入头部信息

<%@  taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
  1. JSTL常用标签
    JSP详析_第27张图片
  • 页面赋值标签 页面取值标签
    语法:
 
 

例:

set 和 out标签展示

out 标签 :

直接取值 :

${msg }

效果:
JSP详析_第28张图片

  • remove标签:删除set标签设置的值

set 和 out标签展示

out 标签 :

直接取值 :

${msg }

JSP详析_第29张图片

  • if标签
    JSP详析_第30张图片
    例:

if标签举例

if输入数字为${num }

结果为偶数

结果为奇数

JSP详析_第31张图片

  • choose标签: if else 结构
    JSP详析_第32张图片

choose标签

输入数字为:${num }

偶数

奇数

  • forEach:实现对集合的遍历
    JSP详析_第33张图片
    forEach有两种组合用法:
    第一种就是遍历集合元素

forEach编辑集合元素

<% List list = new ArrayList(); list.add("A"); list.add("B"); list.add("C"); //保存到request中 request.setAttribute("list",list); %>

第${sta.index+1 }次循环:集合元素为:${s }

JSP详析_第34张图片
第二种就是按次数遍历十次输出1-10


	${i }

在这里插入图片描述
拓展:其他JSTL表达式
fmt标签:用于数据格式化的标签
头部信息:

<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>

举例说明 :

  1. 数字格式化成 钱 的格式展示

格式化标签使用:

没有格式化数字:${money }

已经格式化数字:

JSP详析_第35张图片
2. 格式化时间

格式化标签:

<% Date date = new Date(); %>

正常时间:${now }

格式化好之后的时间:

格式化之后的时间:

没有格式化数字:${money }

已经格式化数字:

JSP详析_第36张图片

response对象

  1. 刚才我们在写转发请求的时候涉及到了一个对象叫做response对象,那么接下来我们就介绍一下这个response对象
    response对象 用于响应客户请求并向客户端输出信息
    什么意思? 举个例子
    request 是页面发送请求到服务器 然后服务器接收数据再做处理 因为客户端与服务器之间传输的都是字符流 所以我们把request 叫做请求流
    response正好相反,服务器处理完了页面请求之后需要发送结果给页面,此时就可以使用response对象,因为它是服务器向客户端发送信息的对象 所以我们把response对象 叫做 响应流
    B/S 请求 与 响应 模式
    request form数据 从页面带到服务端 1) 设置编码 2) 接收数据 3) 保存数据 4) 转发数据
    对于我们来说 response 有一个方法我们需要留意一下 就是 void sendRedirect(String location) 重定向
    sendRedirect 方法叫做重定向,表示本次请求已经处理完,客户端将重新发送请求到指定的URL;
    重定向的特点是 重定向后 request对象会被重置,也就是说request中的信息都会丢失,并且地址栏也会发生改变,改变成新的地址
    看下效果:
    login.jps发送请求给服务器login_server.jsp,如果login_server.jsp使用重定向方式跳转页面的话
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//模拟数据库定义两组人
	//普通用户
	String[] users = {"陈玄伯","杜子美","陈叔同"};
	//VIP用户
	String[] vips = {"张仲景","尹子樵"};
	//设定编码
	request.setCharacterEncoding("UTF-8");
	//接收页面请求
	String userName = request.getParameter("userName");
	//定义最终的展示结果页
	String result = "error.jsp";//默认错误页
	//哦按分段是不是普通用户
	for(String a : users){
		if(userName.equals(a)){
			result = "users.jsp";
			break;
		}
	}
	
	//判断是不是VIP用户
	for(String b : vips){
		if(userName.equals(b)){
			result = "vips.jsp";
			break;
		}
	}
	
	//根据业务结果转发到对应页面
	//request.getRequestDispatcher(result).forward(request,response); 
	//重定向到结果页面
	response.sendRedirect(result);
%>

JSP详析_第37张图片
效果:
JSP详析_第38张图片
转发与重定向的具体应用
什么时候用重定向?
因为它的流程是 页面请求 --> 服务器处理 --> 页面展示 这样三方处理需要数据不丢失的传递下去此时,我们需要用转发做页面与服务器之间的跳转
但是当我们做 添加 修改 删除 操作的时候,这三种操作都会影响我们保存的数据,所以只要你做了三种操作中的任意一种,你之前保存的数据就都不对了,所以
我们需要重新查询数据 从定向 代表本次操作已经完成了 然后开启下一次操作,如果使用重定向也意味着 页面请求 --> 服务器操作 此时服务器操作完 这个业务就结束了;
什么时候用转发?
比如说我们做查询的时候 这个时候 第一个页面发起请求 --> 服务端 处理 数据–> 第三个页面展示 这几个页面之间需要保证是在一次转发链之中 所以他们之间的跳转必须用转发才能完成!

根据我们业务进行区分的话

  1. 数据操作的时候
    1. 事务操作 添加 修改 删除
    2. 非事务的 查询
  2. jdbc操作
    1. queryrunner update 添加 修改 删除
    2. queryrunner query 查询
  3. 页面操作的时候
    1. 重定向 添加操作 更新操作 删除操作 完成之后 肯定是从定向到 查询请求上
    2. 转发 查询的时候因为要保存数据 所以基本都采用转发的形式 跳转下一个页面

JSP第一天课后作业

  1. 主观题
    request和response对象的作用和常用方法是什么?
    request常用方法
    JSP详析_第39张图片

    针对POST请求如何处理中文乱码?
    request.setCharacterEncoding(“UTF-8”);

    转发与重定向的区别和应用场合是什么?
    什么时候用重定向?
    因为它的流程是 页面请求 --> 服务器处理 --> 页面展示 这样三方处理需要数据不丢失的传递下去此时,我们需要用转发做页面与服务器之间的跳转
    但是当我们做 添加 修改 删除 操作的时候,这三种操作都会影响我们保存的数据,所以只要你做了三种操作中的任意一种,你之前保存的数据就都不对了,所以
    我们需要重新查询数据 从定向 代表本次操作已经完成了 然后开启下一次操作,如果使用重定向也意味着 页面请求 --> 服务器操作 此时服务器操作完 这个业务就结束了;
    什么时候用转发?
    比如说我们做查询的时候 这个时候 第一个页面发起请求 --> 服务端 处理 数据–> 第三个页面展示 这几个页面之间需要保证是在一次转发链之中 所以他们之间的跳转必须用转发才能完成!

  2. 编程题
    尝试完成JSP页面的person表的增删改查操作

JSP实战采用model 1模式开发数据库表的增删改查业务

要求:数据库有一张表叫person表,完成person表的页面级别的 查询全部 添加 修改 删除 功能
思路:
构建项目
导入jar包
编写实体类 OOP OM Object Mapping 对象映射 表 --> 类 字段 --> 属性
构建后台数据库连接类 jdbcUtil
构建请求页面
构建控制器页面
构建数据展示页面
完成CURD; 查询 添加 删除 更新

第一部分:项目初始化构建

  1. 构建项目:Java Web项目
    Dynamic Web Project
  2. 导入jar包
    JSP详析_第40张图片

注:以下代码与 "实战案例3:MVC模式与JSTL表达式"中代码一样,可直接跳过,在这个基础上扩展

编写实体类 person.java

package top.mublog.db;
/**
 * 人员信息实体类
 * @author Amanda
 *
 */
public class person {
	//属性
	private Integer pid ; //主键ID
	private String pname; //姓名
	private String sex;  //性别
	private Integer age;  //年龄
	private String pn;  //籍贯
	public Integer getPid() {
		return pid;
	}
	public void setPid(Integer pid) {
		this.pid = pid;
	}
	public String getPname() {
		return pname;
	}
	public void setPname(String pname) {
		this.pname = pname;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getPn() {
		return pn;
	}
	public void setPn(String pn) {
		this.pn = pn;
	}
}

构建后台数据库连接JDBCUtil.Java

package top.mublog.db;

import com.alibaba.druid.pool.DruidDataSource;

/**
 * 数据库连接
 * @author Amanda
 *
 */
public class JDBCUtil {
	
	//创建数据库连接对象
	private static final String CONN_DRIVER = "com.mysql.jdbc.Driver";
//	private static final String CONN_URL = "jdbc:mysql://127.0.0.1:3306/jdbcdb?characterEncoding=UTF-8";
	private static final String CONN_URL = "jdbc:mysql:///jdbc_db?characterEncoding = UTF-8";
	private static final String CONN_USER = "root";
	private static final String CONN_PASSWORD = "123456";
	
	//创建数据源对象
	private static DruidDataSource dataSource = new DruidDataSource();
	
	//赋值
	static{
		dataSource.setDriverClassName(CONN_DRIVER);
		dataSource.setUrl(CONN_URL);
		dataSource.setUsername(CONN_USER);
		dataSource.setPassword(CONN_PASSWORD);
	}
	
	//添加获取数据源的方法
	public static DruidDataSource getDataSource(){
		return dataSource;
	}
}

第二部分:完成查询全部需求

  1. 创建系统首页Honepage.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




Home page


	

欢迎使用人员信息管理系统

请选择您要使用的功能:

  1. 查询全部人员信息
  1. 创建控制器findAll_server.jsp
<%@page import="top.mublog.db.person"%>
<%@page import="org.apache.commons.dbutils.handlers.BeanListHandler"%>
<%@page import="java.util.List"%>
<%@page import="top.mublog.db.JDBCUtil"%>
<%@page import="org.apache.commons.dbutils.QueryRunner"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//查询控制器页面
	
	// 创建SQL的执行的对象
	QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
	//编写SQL语句
	String sql = "SELECT * FROM PERSON";
	//占位符赋值
	//执行 查询 获取一个
	List persons = qr.query( sql, new BeanListHandler(person.class));
	
	//保持模型 下一个页面展示
	request.setAttribute("plist", persons);
	
	//转发
	request.getRequestDispatcher("findAll_view.jsp").forward(request, response);
%>
  1. 展示页面代码findAll_view.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>




人员展示页面


	

展示人员数据

编号 姓名 性别 年龄 籍贯
${p.pid } ${p.pname } ${p.sex } ${p.age } ${p.pn }
  1. 效果展示
    JSP详析_第41张图片
    JSP详析_第42张图片
    注:以上代码均与之前的代码雷同,可直接用之前的代码往下进行!
    第三部分:完成人员添加需求
  2. 首页"添加新人员"连接
  1. 查询全部人员信息
  2. 添加人员信息
  1. 编写添加页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>




添加人员信息


	

添加人员信息

请输入人员姓名:
请选择人员性别:
请输入人员年龄:
请输入人员籍贯:
  1. 编写添加控制器 add_server.jsp
<%@page import="top.mublog.db.JDBCUtil"%>
<%@page import="org.apache.commons.dbutils.QueryRunner"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//添加业务
	//第一阶段 接收数据
	//1. 设定页面请求字符流的编码
	request.setCharacterEncoding("UTF-8");
	//2. 接收页面数据
	String pname = request.getParameter("pname");
	String sex = request.getParameter("sex");
	String age = request.getParameter("age");
	String pn = request.getParameter("pn");
	
	//第二阶段 数据库处理阶段
	// 1. 创建SQL执行对象
	QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
	//2.编写SQL语句
	String sql = "INSERT INTO PERSON VALUES(NULL,?,?,?,?)";
	//3.占位符赋值
	Object[] params = {pname,sex,age,pn};
	//执行SQL语句
	int count = qr.update(sql, params);
	
	//第三阶段 根据数据库的处理结果 进行相应结果处理
	if(count > 0){
		//添加成功
		//重新定向到查询全部页面
		response.sendRedirect("findAll_server.jsp");
	}else{
		//添加失败 response 响应流
		String msg = "";
		//服务器想给客户端发送一段代码 让客户端自动添加失败了
		// 你这段文字到底是模式类型的? text/html 那么浏览器就吧你的这段话当做是HTML文本进行解析
		response.setContentType("text/html;charset=UTF-8");//服务端给客户端发送的数据类型是什么
		//打印回去
		out.print(msg);
	}
%>

注意,页面中 page 是关键字,是JSP的内置对象,所以此处我们不能使用!
效果:
JSP详析_第43张图片JSP详析_第44张图片JSP详析_第45张图片
这个两个’东方来’是因为我把sex的字段名写错了,使用7的没有性别,后来改了再加上!问题不大,后面加上更新需求给她改改
第四部分 : 完成更新人员需求
选择你要更新的数据
展示你要更新的数据
修改数据
提交
如果修改成功 从新查询全部 如果修改失败 返回提示

  1. 数据展示页面添加"更新"和"删除"按钮
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>




人员展示页面


	

展示人员数据

编号 姓名 性别 年龄 籍贯 操作
${p.pid } ${p.pname } ${p.sex } ${p.age } ${p.pn }

JSP详析_第46张图片
2) 编写跳转 JS

function goUpdate(id){
		// 我需要在此处发起一次请求 将要删除的ID传递给服务器 
		window.location.href = "findById_server.jsp?pid="+id;
	}

3) 编写按ID查询人员的控制页面 findById_server.jsp

<%@page import="org.apache.commons.dbutils.handlers.BeanHandler"%>
<%@page import="top.mublog.db.person"%>
<%@page import="top.mublog.db.JDBCUtil"%>
<%@page import="org.apache.commons.dbutils.QueryRunner"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//删除业务
	
	//第一阶段 数据库处理
	//1.设定编码
	request.setCharacterEncoding("UTF-8");
	//2.接收数据
	String pid = request.getParameter("pid");
	
	//第二阶段 数据库处理
	//创建SQL的执行对象
	QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
	//编写SQL语句
	String sql = "SELECT * FROM PERSON WHERE PID = ?";
	//占位符赋值
	Object[] params = {pid};
	//执行
	
	person person = qr.query( sql, new BeanHandler(person.class),params);
	
	//第三阶段 服务器响应
	//保存要更i新的信息
	request.setAttribute("person",person);
	//转发给下一个页面展示person
	request.getRequestDispatcher("update.jsp").forward(request,response);
%>

4) 编写展示要更新人员信息的页面update.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>




更新人会员信息


	

更新人员信息

请输入人员姓名
请选择人员性别:
请输入人员年龄:
请输入人员籍贯:
  1. 编写更新人员信息的控制器 update_server.jsp
<%@page import="top.mublog.db.JDBCUtil"%>
<%@page import="org.apache.commons.dbutils.QueryRunner"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//添加业务
	//第一阶段 接收数据
	//1.设定页面请求字符流的编码
	request.setCharacterEncoding("UTF-8");
	//2.接收页面数据
	String pname = request.getParameter("pname");
	String sex = request.getParameter("sex");
	String age = request.getParameter("age");
	String pn = request.getParameter("pn");
	String pid = request.getParameter("pid");
	
	//第二阶段 数据库处理阶段
	//1.创建SQL执行对象
	QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
	//2.编写SQL语句
	String sql = "UPDATE PERSON SET PNAME = ?,SEX = ?,AGE = ?,PN = ? WHERE PID = ?";
	//3.占位符赋值
	Object[] params = {pname,sex,age,pn,pid};
	//4.执行SQL语句
	int count = qr.update( sql,params);
	//第三阶段 根据数据库处理结果 进行相应结果处理
	if(count > 0){
		//添加成功
		//重定向到查询全部页面
		response.sendRedirect("findAll_server.jsp");
	}else{
		//添加失败 response 响应流
		String msg = "";
		//服务器下给客户端发送一段代码 让客户端知道添加失败了
		//你这段文字到底是什么类型的? text/html  你们浏览器就把你这段话当作是HTML文本进行解析
		response.setContentType("text/html;cahrset=UTF-8"); //服务端给客户端发送的数据类型是什么
		//打印回去
		out.print(msg);
	}
%>

效果:
JSP详析_第47张图片在这里插入图片描述

第四部分:完成删除人员需求
删除 :
首选 选择你要删除的哪一行 点击删除按钮
询问是否删除 如果点击是
删除
删除成功 --> 重新查询全部数据

  1. 编写删除JS脚本
function goUpdate(id){
		// 我需要在此处发起一次请求 将要删除的ID传递给服务器 
		window.location.href = "findById_server.jsp?pid="+id;
	}
	function goDelete(id){
		// 询问一下是否删除
		var con = window.confirm("确定要删除ID为" + id + "的数据么?");
		// 判断
		if(con == true){
			// 我需要在此处发起一次请求 将要删除的ID传递给服务器 
			window.location.href = "delete_server.jsp?pid="+id;
		}
	}
  1. 编写删除的控制页面delete_server.jsp
<%@page import="top.mublog.db.JDBCUtil"%>
<%@page import="org.apache.commons.dbutils.QueryRunner"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%
	//添加业务
	//第一阶段 接收数据
	//1.设定页面请求字符流的编码
	request.setCharacterEncoding("UTF-8");
	//2.接收页面数据
	String pname = request.getParameter("pname");
	String sex = request.getParameter("sex");
	String age = request.getParameter("age");
	String pn = request.getParameter("pn");
	String pid = request.getParameter("pid");
	
	//第二阶段 数据库处理阶段
	//1.创建SQL执行对象
	QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
	//2.编写SQL语句
	String sql = "UPDATE PERSON SET PNAME = ?,SEX = ?,AGE = ?,PN = ? WHERE PID = ?";
	//3.占位符赋值
	Object[] params = {pname,sex,age,pn,pid};
	//4.执行SQL语句
	int count = qr.update( sql,params);
	//第三阶段 根据数据库处理结果 进行相应结果处理
	if(count > 0){
		//添加成功
		//重定向到查询全部页面
		response.sendRedirect("findAll_server.jsp");
	}else{
		//添加失败 response 响应流
		String msg = "";
		//服务器下给客户端发送一段代码 让客户端知道添加失败了
		//你这段文字到底是什么类型的? text/html  你们浏览器就把你这段话当作是HTML文本进行解析
		response.setContentType("text/html;cahrset=UTF-8"); //服务端给客户端发送的数据类型是什么
		//打印回去
		out.print(msg);
	}
%>

实战终于完了,我中间字段名经常写错,快崩溃了,大家好好加油呀!

你可能感兴趣的:(JSP)