5. jsp组件

5.1 概念

是javaEE的一个组件,用于做动态页面,必须借助于服务器【容器–Tomcat】运行。

是由静态页面【html+css+js】+java代码组成。

5.2 jsp页面的定义

以jsp为扩展名的文件

5.3 主要考虑解决的问题

Question:静态页面和java代码如何整合到一起?

主导是页面–用于显示数据,主要还是以静态页面作为整个架构;

java代码是辅助页面动态加载显示数据。

Question:如何在页面上放java代码?

提供了三个标签或者知识点来完成此任务。

  • <%! 定义方法或者函数 %> :jsp的声明
  • <% java代码 %> : jsp的脚本
  • <%=需要显示的内容 %> : jsp的表达式

<%-- 注释内容 --%> : 注释

5.4 jsp的实现原理【执行过程】

首先,创建一个jsp页面,提交请求访问jsp页面。

Tomcat找到对应的jsp页面将其翻译成java代码【固定模板】–放到Tomcat目录下的work目录下【本地目录下查看】;

Tomcat会将java类编译成字节码文件【.class】;

Tomcat会创建此类的对象;

Tomcat调用此类对象中的jspService方法,通过流的形式将处理完java代码的页面响应给客户端浏览器。

简化执行过程:

jsp–翻译成–java代码–编译–.class文件–创建对象–调用service方法。

几种元素的翻译过程:

  • html标签 --直接翻译成out.write(“标签”)
  • <%!声明 %> --直接翻译到类的最前面
  • <% 脚本 %> --直接将<% %>去掉放到service方法中的对应位置
  • <%=表达式 %> --直接翻译成out.write(表达式)

5.5 jsp本质

还是一个servlet,遵循servlet的规范,容器运行。

证明:

  1. 继承关系
    jsp–翻译成java代码,转化成一个最终类,继承了HttpJspBase。
    HttpJspBase是一个抽象类,是所有 JSP 生成的 servlet 的子类;
    定义方法:
  • service() --业务处理
  • destory() --销毁
  • init() --初始化
  • getIncludes() --获取 JSP 文件使用的编译时包含文件的列表。
  • jspInit()
  • jspService()
  • jspDestory()

HttpJspBase继承了HttpServlet,实现了HttpJspPage接口。

HttpServlet也是一个抽象类。[参考本文档2.3 HttpServlet]

  • 定义常量–存储HTTP请求方法
  • 定义方法:–方法不被允许的时候,显示的信息

HttpServlet继承了GenericServlet。[参考本文档2.4 GenericServlet]

httpJspPage接口实现了servlet(),JspPage接口(两个抽象方法jspDestroy,jspInit)而本身创建jspservice(request,response)方法,用于JSP页面工作,同时继承了jspPage两个抽象方法又从继承的servlet接口中实现了destroy,getServletConfig,getServletInfo,init,service(五个),所以HttpJsppage共实现了七个父类接口的抽象方法(jspPage两个,Servlet五个),本身创建一个jspService方法用于jsp页面工作。

  1. 原理分析
  • jsp–最终的运行形态–java类有特点:
  • 继承规范、代码模板、service方法调用、out.write()写页面。

2. 探索jsp组件

2.1 复习回顾

昨日课程知识点回顾

jsp概念

是javaEE的一个组件,用于做动态页面,必须借助于服务器【容器–Tomcat】运行;

是由静态页面【html+css+js】+java代码组成。

问题

静态页面和java代码如何整合到一起?【参考本文档 八、5.3】

如何在页面上放java代码?【参考本文档 八、5.3】

/

/

内置对象

什么时候生成的?
jsp页面翻译成java类的时候定义创建 --jspService方法

2.2 内置对象

含义:内置对象也是对象,不需要创建,是由服务器自动创建提供,可以直接在jsp页面上使用。

特点:内置对象是固定的,不能修改。

  • request–请求对象:service方法参数
  • response --响应对象:service方法参数

service方法里面模板创建的固定内置对象:

  • pageContext
  • session --绘制对象
  • application --上下文对象
  • config --获取service的配置信息
  • out --打印流
  • page --页面相关
  • [exception]

总共有九大内置对象。

3.探索jsp和servlet之间的数据传输问题

3.1 需要传输数据的位置

  • jsp向servlet传输数据 [请求参数]
  • servlet向servlet传输数据 [请求参数/请求属性]
  • servlet向jsp传输数据 [请求属性]
  • jsp向jsp传输数据 [请求参数/请求属性]

3.2 传输数据的方式

请求参数:

  • form表单提交数据
  • 使用url地址提交数据 【url?参数名=参数值】

获取:

HttpServletRequest 对象里面方法

  • getParameter(“参数名”);
  • getParameterValues(“参数名”);

功能:页面向servlet传递数据。

请求属性

获取:

HttpServletRequest对象里面方法

  • setAttribute(“属性名,属性值”) 设置属性值
  • Object getAttribute(“属性名”) 获取属性值

3.3 对比总结:请求参数和请求参数

请求参数:

  • 是请求对象HttpServletRequest提供服务的
  • 自动添加到请求中的
  • 通过请求中的getParameter或者getParameterValues获取
  • 返回值是Stirng或者String[]

传入数据【 参考本文档 九、3.2】

请求属性:

  • 是请求对象HttpServletRequest提供服务的
  • 通过setAttribute(String,Object) 方法手动的将数据以Object类型放入请求对象;
  • 通过getAttribute(String) 方法获取数据,获取的数据是object类型,要想使用–必须转型–转换成原来类型【强转】

4. 实战-用户信息管理案例

4.1 创建项目

新建页面:登录(login.jsp)、注册(register.jsp)、主页(main.jsp)

新建Servlet:登录(LoginServlet)、注册(RegisterServlet)、数据删除(DeleteSeervlet)

新建Dao:UserData【用于模拟数据库中的数据处理】

4.2 思路【流程】

  1. 进入登录界面–权限就一个
  2. 如果账号密码不存在–跳到注册页面–注册信息–跳转的登录页面
  3. 如果密码错误–跳到登录界面,并且提示密码错误
  4. 如果账号密码都对–获取所有的用户信息跳转到主页面显示
  5. 在主页面上–可以删除某一个用户
package pers.wcs.usermanager.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import pers.wcs.usermanager.dao.UserData;

/**
 * Servlet implementation class LoginServlet
 */
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 设置编码
		request.setCharacterEncoding("UTF-8");
		// 获取请求参数
		String name = request.getParameter("uname");
		String password = request.getParameter("passw");
		int index = 0;
		// 判断账号密码是否在集合中
		if (name != null && name != "" && password != null && password != "") {
			// 循环遍历
			for (String[] str : UserData.users) {
				// 判断集合中是否有此账号密码
				if (name.equals(str[0]) && password.equals(str[1])) {
					// 改变状态
					index = 1;
					// 结束
					break;
				} else if (name.equals(str[0]) && !password.equals(str[1])) {
					// 改变状态
					index = 2;
					// 结束
					break;
				} else {
					index = 3;
					break;
				}
			}
		} else {
			// 带数据
			request.setAttribute("msg", "账号或者密码为空!");
			// 跳转到登录界面
			request.getRequestDispatcher("login.jsp").forward(request, response);
		}
		// 循环结束再进行跳转
		if (index == 1) {
			request.setAttribute("list", UserData.users);
			// 登录成功,跳转到主页面
			request.getRequestDispatcher("main.jsp").forward(request, response);
		} else if (index == 2) {
			request.setAttribute("msg", "密码有误!请查证后再尝试登录!");
			// 密码错误
			request.getRequestDispatcher("login.jsp").forward(request, response);
		} else if (index == 3) {
			request.setAttribute("msg", "账号不存在,请重新注册!");
			// 账号有误
			request.getRequestDispatcher("register.jsp").forward(request, response);
		}

	}

}
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
#content {
	width: 280px;
	height: 320px;
	background-color: #ffe;
	border: 5px solid red;
	border-radius: 20px;
	margin: auto;
	margin-top: 10%;
	text-align: center;
}

#but {
	width: 200px;
}
</style>
</head>
<body>
	<div>
		<div id="content">
			<form action="LoginServlet" method="post">
				<h1>登录界面</h1>
				<br> 账号:<input type="text" name="uname"> <br>
				<br> 密码:<input type="text" name="passw"> <br>
				<br> <input type="submit" id="but" value="登录"> <br>
				<br>
			</form>
			<h4 style="color: red"><%=request.getAttribute("msg")%></h4>
		</div>
	</div>
</body>
</html>
package pers.wcs.usermanager.dao;
/**
 * 	
 * @author WCS
 * @version V.1.0.1
 * @date 2021-12-16 03:31
 * 	需求:用于模拟数据库中的数据处理
 * 	思路分析:
 * 	问题汇总:
 */

import java.util.ArrayList;
import java.util.List;

public class UserData {
	//输出处理
	public static List<String[]> users=new ArrayList<String[]>();
	
	//存入数据
	static {
		users.add(new String[]{"张三","123","法外狂徒"});
		users.add(new String[]{"李四","456","逃犯"});
		users.add(new String[]{"王五","789","警察"});
		users.add(new String[]{"罗翔","147","被告方律师"});
		users.add(new String[]{"大状","258","原告方律师"});
		users.add(new String[]{"Black","369","法官"});
	}

	/**
	 * 
	 * 需求:获取集合大小    	
	 * @author WCS
	 * @date 12-16 04:01:27
	 * @return
	 */
	public int getSize(){
		//返回
		return users.size();
	}
	
	/**
	 * 
	 * 需求: 删除数据    	
	 * @author WCS
	 * @date 12-16 04:01:17
	 * @param name
	 * @return
	 */
	public boolean delete(String name){
		boolean flag=false;
		//遍历
		for (String[] str : users) {
			//判断
			if (name != null&&name.equals(str[0])) {
				//删除
				flag=users.remove(str);
				//结束循环
				break;
			}
		}
		//返回结果
		return flag ;
	}
}
<%@page import="java.util.List"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
	pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<style>
table {
	width: 400px;
	height: 300px;
	text-align: center;
}
</style>
</head>
<body>
	<table border=2px>
		<tr>
			<th>账号</th>
			<th>密码</th>
			<th>描述</th>
			<th>操作</th>
		</tr>
		<%
		//获取用户集合
		List<String[]> list = (List<String[]>) request.getAttribute("list");
		//遍历
		for (String[] str : list) {
		%>
		<tr>
			<td><%=str[0]%></td>
			<td><%=str[1]%></td>
			<td><%=str[2]%></td>
			<td><input type="button" value="删除"></td>
		</tr>
		<%
		}
		%>
	</table>
</body>
</html>