文章目录
一、JSP页面
(一)概念以及为什么要有JSP页面?
1.HTML页面属于一种静态页面,而JSP是一种动态页面
2.HTML页面和JSP页面最大的区别是:在HTML中只能定义CSS、JS等,在JSP中除了可以定义CSS和JS以外还可以定义Java代码,并且还可以在JSP中使用EL表达式和JSTL标签
3.但是Java代码必须使用<%Java代码%>的格式
(二)EL表达式和Scriptlet标签的区别
1.EL表达式不仅仅可以输出一个变量的值,还可以输出对象的内容
2.只要将数据保存到内置对象就能在JSP中使用EL表达式获取
(三)JSP访问过程
第一次访问:
1.将访问的JSP页面转换成对应的*.java文件
2.将转换后的*.java文件编译成*.class文件
3.将*.class文件解释成*.html页面响应给浏览器
如果是第二次访问:
1.JSP被修改了:此时重新执行上面三个步骤
2.JSP没有被修改:直接执行第三步骤
(四)总结
1.和静态页面向比可以在JSP中定义Java代码
2.和静态页面相比:可以使用EL表达式获取内置对象的属性
3.其实JSP是会被转换成一个特殊的Servlet
(三)DEMO
1.JSP页面默认的格式:
<!-- jsp的page指令,指定了页面的编码以及MIME类型 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
</body>
</html>
2.在JSP中定义Java代码:<%Java代码%>
<%=变量名>,Scriptlet表达式(???没说用途)
<body>
<h1>首页</h1>
<%
System.out.println("Jsp Hello World");
String sid = session.getId();
System.out.println(sid);
%>
<!-- 可以通过Scriptlet表达式取得Java中定义的变量 -->
<%=sid%>
</body>
运行结果
3.使用EL表达式输出sid
将数据保存到内置对象才能在JSP中使用EL表达式获取
<body>
<h1>首页</h1>
<%
System.out.println("Jsp Hello World");
String sid = session.getId();
/* 将数据保存到内置对象才能在JSP中使用EL表达式获取 */
session.setAttribute("sid", sid);
%>
<h1>${sid}</h1>
</body>
二、JSP注释
1.原有的html注释:<!--html注释-->
2.单行注释://注释的内容(需要在<%%>中定义)
3.多行注释:/*注释内容*/(需要在<%%>中定义)
4.jsp特有注释:<%--注释内容--%>
jsp特有的主食在页面使用查看源码的方式不能看见
html的注释 在页面使用查看源码的方式可以看见
三、JSP两种包含
(一)为什么要有包含?
1.在一个项目中会出现多个页面,但是这些页面的头部信息和尾部信息可能是一样的,此时就需要在多个页面中编写相同的代码,这样会出现代码的重复现象
2.最好的解决方案就是将头部信息和尾部信息定义到独立的文件中,之后在需要的地方包含就行
(二)两种包含方式
1.静态包含:<% @ include file=“被包含的文件路径” %>
2.动态包含:<jsp:include page=“被包含的文件路径” />
//静态包含:最终生成一个*.class文件,证明是在编译之前先将需要导入的文件包含进来之后成为一个页面再进行转换,所有最终编译出一个*.class
<body>
<%@include file="header.jsp" %>
<h1>主体部分的图片、文字等</h1>
<%@include file="footer.jsp" %>
</body>
//动态包含:最终生成3个*.class文件,证明了使用动态包含会将需要导入的文件先编译成独立的*.class文件,之后再包含到目标页面
<body>
<jsp:include page="header.jsp" />
<h1>主体部分的图片、文字等</h1>
<jsp:include page="footer.jsp" />
</body>
//header.jsp
<%@ page pageEncoding="UTF-8"%>
<h1>
<%=request.getParameter("color") %>
</h1>
//footer.jsp
<%@ page pageEncoding="UTF-8"%>
<h1>
我是尾部信息
</h1>
(三)面试题:静态包含和动态包含的区别?
静态包含
1.语法:<%@ include file=“路径” %>
2.先将需要导入的文件包含之后再编译成一个*.class文件
动态包含
1.语法:<jsp:include page=“路径” />
2.如果被包含的文件是静态资源,和静态包含是一样的
3.如果包含的是动态资源,则会先将被包含的资源编译成独立的class文件再进行包含
四、EL表达式(expression language)
(一)概念
1.EL表达式是一种再JSP页面获取数据的简单方式(只能获取数据,不能设置数据)
2.主要功能:取得保存在内置对象中的数据显示到JSP页面
3.需要先将只保存到内置对象的属性中,再进行获取
(二)运算符
在EL表达式中我们可以使用运算符以达到我们想要的结果,运算符按作用分为以下几种:
1.算数运算符:==在EL表达式中 + 只有数学运算的功能,没有连接符的功能,它会试着把运算符两边的操作数转换为数值类型,进而进行数学加法运算,最后把结果输出,若出现 ${‘a’ + ‘b’}则会出现异常 ==
${4+3}
${4-3}
${4*3}
${9/3}
2.关系运算符
> 或者 gt:${8>9} 或者 ${8 gt 9}
>= 或者 ge:${8>=9} 或者 ${8 ge 9}
< 或者 lt:${8>9} 或者 ${8 lt 9}
<= 或者 le:${8>9} 或者 ${8 le 9}
= 或者 eq:${8=9} 或者 ${8 eq 9}
!= 或者 eq:${8!=9} 或者 ${8 ne 9}
3.逻辑运算符
&& 或者 and:${false && false} 或者 ${false and false}
|| 或者 or:${false || false} 或者 ${false or false}
! 或者 not:${!false} 或者 ${not false}
<h1>
薪资是: ${ emp.sal ne 3000 || emp.ename eq 'SCOTT' }
</h1>
4.三元运算符 ${3>2?‘value1’:‘value1’}
5.特殊运算符
(1)empty: ${empty sessionScope.user} 判断EL表达式是否为空
(2)" . ": 最常用的,作用相当于执行Bean中的get方法
${sessionScope.user.userName}:在会话中得到名称为user的Bean对象,通过“.”运算符执行getUserName()方法,返回存放在Bean中的用户名属性的值
(3)[]:作用和“.”运算符的一样,只不过[]运算符可以执行一些不规则的标识符
${user["score-smith"]}:这个表达式中有不规则的标识符,不能使用“.”来访问
五、JSTL的使用
(一)为什么要有JSTL?
下面的代码片段来自某个JSP文件,使用了EL表达式显示了一个雇员的信息,但是如果查询的数据不是一个,而是多个,此时单独使用EL表达式就无法显示这样的数据,那么就需要使用到JSTL标签库,使用这个标签库就可以迭代查询到的集合显示到页面
<tr>
<td>${emp.empno}</td><td>${emp.ename}</td><td>${emp.job}</td><td>${emp.mgr}</td><td>${emp.sal}</td><td>${emp.hiredate}</td><td>${emp.comm}</td><td>${emp.deptno}</td>
</tr>
(二)使用JSTL
遍历集合方法
<!--遍历集合方法-->
<c:foreach iterms="${list}" var="temp">
items:指定要迭代的集合,使用EL表达式取得这个集合
var="temp":将每次迭代到的数据保存到这个叫做temp的临时变量中(可以使用其他命名)
1.需要下载JSTL的开发包(jstl-api.jar 和 standard.jar)
2.将开发包直接拷贝到lib目录下
3.在控制层中定义查询集合的方法
//浏览器输入:http://localhost/ServletProject/emp/emps即可调用显示
//控制层
@WebServlet(urlPatterns = { "/emp/*" })
public class EmpServlet extends BaseServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getPathInfo();
if(path.equals("/emps")) {
this.getEmpList(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
/**
* 查询所有雇员的信息
* @param req
* @param resp
*/
public void getEmpList(HttpServletRequest req, HttpServletResponse resp) {
// 获取到业务层的对象
IEmpService service = new EmpServiceImpl();
// 用业务层对象获取到Emp对象的集合,显示一页,3条数据
Map<String, Object> map = service.findSplitAll("", 1, 6);
System.out.println(map);
// 新建List对象接收Emp对象集合
List<Emp> list = new ArrayList<Emp>();
list = (List) map.get("emps");
System.out.println(list);
// 将集合保存到req对象的list属性中
req.setAttribute("list", list);
// 跳转到index.jsp中显示数据
try {
req.getRequestDispatcher("/demo.jsp").forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//service层实现类
public class EmpServiceImpl implements IEmpService{
Connection conn = C3P0Util.getConnection();
private IEmpDao empDao = new EmpDaoImpl(conn);
@Override
public Map<String,Object> findSplitAll(String kw, Integer cp, Integer ls) {
//创建map对象,将职位存储到键,所有该职位的Emp对象的集合存储到值进行保存,
Map<String,Object> map = new HashMap<String,Object>();
try {
map.put("emps", empDao.selectSplitAll(kw, cp, ls));
map.put("count", empDao.selectCount(kw));
} catch (SQLException e) {
e.printStackTrace();
}finally {
C3P0Util.close(conn);
}
return map;
}
}
4.将查询的数据显示到jsp页面
<!-- jsp的page指令,指定了页面的编码以及MIME类型 -->
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<table border="1">
<tr>
<td>编号</td><td>姓名</td><td>职位</td><td>领导编号</td><td>薪资</td><td>入职日期</td><td>佣金</td><td>部门编号</td>
</tr>
<c:forEach items="${list}" var="emp">
<tr>
<td>${emp.empno}</td><td>${emp.ename}</td><td>${emp.job}</td><td>${emp.mgr}</td><td>${emp.sal}</td><td>${emp.hiredate}</td><td>${emp.comm}</td><td>${emp.deptno}</td>
</tr>
</c:forEach>
</table>
</body>
</html>
运行结果:成功将6条数据显示到jsp页面
六、遍历map集合
(一)将雇员按照部门分组显示
1.定义控制层方法
//浏览器输入:http://localhost/ServletProject/emp/get即可调用显示
//控制层
@WebServlet(urlPatterns = { "/emp/*" })
public class EmpServlet extends BaseServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getPathInfo();
if(path.equals("/get")) {
this.getEmpsByDept(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
/**
* 实现对map集合的遍历
* @param req
* @param resp
*/
public void getEmpsByDept(HttpServletRequest req, HttpServletResponse resp) {
Map<String, Object> map = new HashMap<String, Object>();
// 创建出10号部门的员工
List<Emp> list10 = new ArrayList<Emp>();
for (int i = 1; i <= 5; i++) {
Emp emp = new Emp(1001, "xx" + i, "职员" + i, 7788, 1000.0, new Date(), 200.0, 10, "");
list10.add(emp);
}
map.put("dept10", list10);
// 创建出10号部门的员工
List<Emp> list20 = new ArrayList<Emp>();
for (int i = 1; i <= 5; i++) {
Emp emp = new Emp(1002, "xx" + i, "职员" + i, 7788, 1000.0, new Date(), 200.0, 20, "");
list20.add(emp);
}
map.put("dept20", list20);
// 创建出10号部门的员工
List<Emp> list30 = new ArrayList<Emp>();
for (int i = 1; i <= 5; i++) {
Emp emp = new Emp(1003, "xx" + i, "职员" + i, 7788, 1000.0, new Date(), 200.0, 30, "");
list30.add(emp);
}
map.put("dept30", list30);
// 创建出10号部门的员工
List<Emp> list40 = new ArrayList<Emp>();
for (int i = 1; i <= 5; i++) {
Emp emp = new Emp(1004, "xx" + i, "职员" + i, 7788, 1000.0, new Date(), 200.0, 40, "");
list40.add(emp);
}
map.put("dept40", list40);
//再把map集合保存到Request对象empMap属性中
req.setAttribute("empMap", map);
//之后跳转到index.jsp页面
try {
req.getRequestDispatcher("/index.jsp").forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
2.将数据显示到JSP页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:forEach items="${empMap}" var="list">
<p>${list.key}</p>
<table border="1">
<tr>
<td>编号</td><td>姓名</td><td>职位</td><td>领导编号</td><td>薪资</td><td>入职日期</td><td>佣金</td><td>部门编号</td>
</tr>
<c:forEach items="${list.value}" var="emp">
<tr>
<td>${emp.empno}</td><td>${emp.ename}</td><td>${emp.job}</td><td>${emp.mgr}</td><td>${emp.sal}</td><td>${emp.hiredate}</td><td>${emp.comm}</td><td>${emp.deptno}</td>
</tr>
</c:forEach>
</table>
</c:forEach>
</body>
</html>
运行结果:分部门将数据都显示到JSP页面中
(二)按照职位分组显示雇员的信息
1.定义控制层方法
//浏览器输入:http://localhost/ServletProject/emp/job即可调用显示
//控制层
@WebServlet(urlPatterns = { "/emp/*" })
public class EmpServlet extends BaseServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = req.getPathInfo();
if(path.equals("/job")) {
this.getEmpsByDept(req, resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
/**
* 按照职位分组显示雇员的信息
* @param req
* @param resp
*/
public void getEmpsGroupByJob(HttpServletRequest req,HttpServletResponse resp) {
//获取到业务层对象
IEmpService service = new EmpServiceImpl();
Map<String, Object> map = service.findSplitAll("", 1, 100);
//将获取到分组后的Map集合对象保存到Request属性
req.setAttribute("empMap", map);
//之后一定要记得跳转到index.jsp观察生成的表单
try {
req.getRequestDispatcher("/index.jsp").forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//service实现层
public class EmpServiceImpl implements IEmpService{
Connection conn = C3P0Util.getConnection();
private IEmpDao empDao = new EmpDaoImpl(conn);
@Override
public Map<String,Object> findSplitAll(String kw, Integer cp, Integer ls) {
//创建map对象,将职位存储到键,所有该职位的Emp对象的集合存储到值进行保存,
Map<String,Object> map = new HashMap<String,Object>();
try {
//调用dao层方法获取到Emp对象的集合
List<Emp> list = empDao.selectSplitAll(kw, cp, ls);
//调用groupByJob,将要分组的Emp对象的List集合,以及将结果集合传递给该方法,利用该方法将引用的值改变
this.groupByJob(list, map);
} catch (SQLException e) {
e.printStackTrace();
}finally {
C3P0Util.close(conn);
}
return map;
}
/**
* 该方法可以对传入进来的Emp对象的集合,生成一个Map集合,该集合按照职位进行分组,并将职位保存到键,所有该职位的对象的集合保存到值
* @param list 传入的Emp对象的集合
* @param map 按照职位分组后生成的Map集合
*/
public void groupByJob(List<Emp> list,Map<String,Object> map) {
//将包含了所有Emp对象的集合参数传递进来,以获得所有的工作信息
for (Emp emp : list) {
String job = emp.getJob();
if(map.containsKey(emp.getJob())) {
//如果map集合的键没有该职位,获取该职位对应的Emp的List集合,并将新的数据添加到集合中
List empList = (List)map.get(emp.getJob());
empList.add(emp);
} else {
//如果map集合的键没有该职位,那么将增加这个键,并且将该职位的Emp对象保存到集合中,添加到值
List newList = new ArrayList<Emp>();
newList.add(emp);
map.put(emp.getJob(), newList);
}
}
}
}
2.将数据显示到JSP页面
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<c:forEach items="${empMap}" var="list">
<p>${list.key}</p>
<table border="1">
<tr>
<td>编号</td><td>姓名</td><td>职位</td><td>领导编号</td><td>薪资</td><td>入职日期</td><td>佣金</td><td>部门编号</td>
</tr>
<c:forEach items="${list.value}" var="emp">
<tr>
<td>${emp.empno}</td><td>${emp.ename}</td><td>${emp.job}</td><td>${emp.mgr}</td><td>${emp.sal}</td><td>${emp.hiredate}</td><td>${emp.comm}</td><td>${emp.deptno}</td>
</tr>
</c:forEach>
</table>
</c:forEach>
</body>
</html>
运行结果:按职位分组显示了雇员的信息