一、JSP代码编写
1. 目录结构
![这里写图片描述](//img-blog.csdn.net/20180316170911959?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
2.hello.jsp
<%@page pageEncoding="utf-8"%>
<!-- 1.先写标签 -->
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>第1个JSP</title>
</head>
<body>
<!-- 2.3 jsp声明 -->
<%!
public double bai(double d) {
return d*100;
}
%>
<ul>
<!-- 2.再写Java -->
<!-- 2.1 jsp脚本 -->
<%
for(int i=0;i<10;i++) {
%>
<!-- 2.2 jsp表达式 -->
<li><%=bai(Math.random()) %></li>
<%
}
%>
</ul>
<!-- 引入一个jsp,就相当于将此jsp的内容复制到此处 -->
<%@include file="time.jsp"%>
</body>
</html>
3. time.jsp
![这里写图片描述](//img-blog.csdn.net/20180316170930192?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
<!--
pageEncoding: 声明此jsp文件的编码
contentType: 声明此jsp向浏览器输出的内容格式
import:导包
-->
<%@page pageEncoding="utf-8" contentType="text/html"
import="java.util.*,java.text.*"%>
<%
Date d = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
String time = sdf.format(d);
%>
<!-- 此jsp被其他网页所引用,是其他网页的一部分,所以不必写出完整结构 -->
<p><%=time %></p>
![这里写图片描述](//img-blog.csdn.net/20180316170941495?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
二、 JSP运行原理
![这里写图片描述](//img-blog.csdn.net/20180316170953705?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
![这里写图片描述](//img-blog.csdn.net/20180316171009476?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
三、JSP隐含(内置)对象(面试题,名称记住)
1.request(*)
2.response
3.out
4.config
5.application
6.exception
- Throwable
- JSP翻译成的Servlet所抛出的异常
7.session(*)
8.page
- Object
- 相当于this,用来指代翻译成的那个Servlet
9.pageContext(*)
- PageContext
- 是管理者,通过它可以获取其他8个隐含对象
![](92.png)
如何在JSP上使用隐含对象
- <%Object user = sesstion.getAttribute(“uesr”);%>
- <%=sesstion.getAttribute(“user”);%>
四、开发模式
1.Model1
![这里写图片描述](//img-blog.csdn.net/20180316171025750?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
目录结构
![这里写图片描述](//img-blog.csdn.net/20180316171057291?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
EmpDao.java
package dao;
import java.util.List;
import entity.Emp;
public interface EmpDao {
List<Emp> findAll();
void save(Emp e);
}
EmpDaoImpl.java
package dao;
import java.util.ArrayList;
import java.util.List;
import entity.Emp;
public class EmpDaoImpl implements EmpDao {
public List<Emp> findAll() {
//模拟查询所有的员工
List<Emp> list = new ArrayList<Emp>();
Emp e1 = new Emp();
e1.setEmpno(1);
e1.setEname("唐僧");
e1.setJob("领导");
e1.setSal(9000.0);
list.add(e1);
Emp e2 = new Emp();
e2.setEmpno(2);
e2.setEname("悟空");
e2.setJob("职员");
e2.setSal(5000.0);
list.add(e2);
Emp e3 = new Emp();
e3.setEmpno(3);
e3.setEname("八戒");
e3.setJob("职员");
e3.setSal(6000.0);
list.add(e3);
return list;
}
//模拟增加一个员工
public void save(Emp e) {
System.out.println("增加了员工: " + e.getEname());
}
}
Emp.java
package entity;
import java.io.Serializable;
/**
* 建议:
* 1.尽量使用封装类型,因为它比基本类型多了null
* 2.使用java.sql包下的日期,因为JDBC支持这样的日期类型
*
*/
public class Emp implements Serializable {
private Integer empno;
private String ename;
private String job;
private Double sal;
public Integer getEmpno() {
return empno;
}
public void setEmpno(Integer empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
}
find_emp.jsp
<%@page pageEncoding="utf-8" import="entity.*,dao.*,java.util.*"%>
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>查询员工</title>
<style>
table {
border: 1px solid red;
border-collapse: collapse;
}
td {
border: 1px solid red;
}
</style>
</head>
<body>
<table>
<tr>
<td>编号</td>
<td>姓名</td>
<td>职位</td>
<td>薪资</td>
</tr>
<%
EmpDao dao = new EmpDaoImpl();
List<Emp> list = dao.findAll();
if(list != null){
for(Emp e : list) {
%>
<tr>
<td><%=e.getEmpno() %></td>
<td><%=e.getEname() %></td>
<td><%=e.getJob() %></td>
<td><%=e.getSal() %></td>
</tr>
<%
}
}
%>
</table>
</body>
</html>
![这里写图片描述](//img-blog.csdn.net/20180316171118695?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
2.Model2
![这里写图片描述](//img-blog.csdn.net/20180316171130514?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
目录结构
![这里写图片描述](//img-blog.csdn.net/20180316171140461?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
FindEmpServlet.java
package web;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import dao.EmpDao;
import dao.EmpDaoImpl;
import entity.Emp;
public class FindEmpServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
//查询所有的员工(处理业务)
EmpDao dao = new EmpDaoImpl();
List<Emp> list = dao.findAll();
//(转发):让jsp继续完成这个请求
//将数据绑定到request上
req.setAttribute("emps", list);
//将请求转发给emp_list.jsp
//当前: /jsp2/findEmp
//目标: /jsp2/emp_list.jsp
req.getRequestDispatcher("emp_list.jsp").forward(req, res);
}
}
web.xml配置文件
<servlet>
<servlet-name>findEmp</servlet-name>
<servlet-class>web.FindEmpServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>findEmp</servlet-name>
<url-pattern>/findEmp</url-pattern>
</servlet-mapping>
emp_list.jsp
<%@page pageEncoding="utf-8" import="java.util.*,entity.*"%>
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>查询员工</title>
<style>
table {
border: 1px solid red;
border-collapse: collapse;
}
td {
border: 1px solid red;
}
</style>
</head>
<body>
<table>
<tr>
<td>编号</td>
<td>姓名</td>
<td>职位</td>
<td>薪资</td>
</tr>
<%
List<Emp> list = (List<Emp>)request.getAttribute("emps");
if(list != null){
for(Emp e : list) {
%>
<tr>
<td><%=e.getEmpno() %></td>
<td><%=e.getEname() %></td>
<td><%=e.getJob() %></td>
<td><%=e.getSal() %></td>
</tr>
<%
}
}
%>
</table>
</body>
</html>
![这里写图片描述](//img-blog.csdn.net/20180316171153250?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
五、转发和重定向
![这里写图片描述](//img-blog.csdn.net/20180316171222819?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
六、EL和JSTL
1.作用
![这里写图片描述](//img-blog.csdn.net/20180316171232797?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
2.案例
![这里写图片描述](//img-blog.csdn.net/20180316171245600?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
目录结构
![这里写图片描述](//img-blog.csdn.net/20180316171303978?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
JSTL导包
![这里写图片描述](//img-blog.csdn.net/20180316171318681?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
Course.java
package entity;
import java.io.Serializable;
public class Course implements Serializable {
//对象的属性
private Integer courseId;
private String name;
private Integer days;
//Bean属性:和get/set对应的属性叫Bean属性
//1.去掉get/set剩下的单词,首字母小写
//2.通过get/set方法所分析出来的属性
//Bean属性通常都和对象属性一致,也可以修改为不一致
public Integer getId() {
return courseId;
}
public void setId(Integer courseId) {
this.courseId = courseId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getDays() {
return days;
}
public void setDays(Integer days) {
this.days = days;
}
}
Student.java
package entity;
import java.io.Serializable;
public class Student implements Serializable {
private String name;
private Integer age;
private String sex;
private String[] interests;
private Course course;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String[] getInterests() {
return interests;
}
public void setInterests(String[] interests) {
this.interests = interests;
}
public Course getCourse() {
return course;
}
public void setCourse(Course course) {
this.course = course;
}
}
FindStudentServlet.java
package web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import entity.Course;
import entity.Student;
public class FindStudentServlet extends HttpServlet {
@Override
protected void service(
HttpServletRequest req,
HttpServletResponse res) throws ServletException, IOException {
//1.获取参数(略)
//2.模拟查询学生(查)
Student s = new Student();
s.setName("zhangsan");
s.setAge(25);
s.setSex("M");
s.setInterests(new String[]{"篮球","足球","排球"});
Course c = new Course();
c.setId(1);
c.setName("Java");
c.setDays(85);
s.setCourse(c);
//3.将数据绑定到request上
req.setAttribute("stu", s);
//4.将请求转发给student.jsp
//当前:/jsp3/findStudent
//目标:/jsp3/find_student.jsp
req.getRequestDispatcher("find_student.jsp").forward(req, res);
}
}
find_student.jsp
<%@page pageEncoding="utf-8"%>
<!-- 引入JSTL标签库 -->
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!-- 引入自定义标签库 -->
<%@taglib uri="/dany_tags" prefix="s" %>
<!doctype html>
<html>
<head>
<meta charset="utf-8"/>
<title>查询学生EL和JSTL</title>
</head>
<body>
<h1>EL</h1>
<!-- 1.EL表达式 -->
<!-- 1.1访问Bean的属性 -->
<!-- request.getAttribute("stu").getName() -->
<p>姓名:${stu.name }</p>
<p>年龄:${stu['age'] }</p>
<!-- request.getAttribute("stu").getId() -->
<p>课程:${stu.course.id }</p>
<!-- EL表达式的取值范围:
它默认从4个隐含对象内依次取值:
page->request->session->application
也可以明确指定取值范围:
如: requestScope.stu.name
sessionScope.stu.name
这样设计的目的,是为了开发者不用经常写范围,是为了简化EL表达式
-->
<p>性别:${requestScope.stu.sex }</p>
<!-- 1.2支持运算 -->
<p>年龄+3:${stu.age+3 }</p>
<p>介于20-30间:${stu.age>20 && stu.age<30 }</p>
<p>是否为空:${empty stu.interests }</p>
<!-- 1.3获取请求参数
通过访问路径:/jsp3/findStudent?uesr=abc
传入user
-->
<p>参数:${param.user }</p>
<!-- 2.JSTL标签 -->
<!-- 2.1 if标签 -->
<h1>JSTL</h1>
<p>
性别:
<c:if test="${stu.sex=='M' }">男</c:if>
<c:if test="${stu.sex=='F' }">女</c:if>
</p>
<!-- 2.2 choose标签 -->
<p>
性别:
<c:choose>
<c:when test="${stu.sex=='M' }">男</c:when>
<c:otherwise>女</c:otherwise>
</c:choose>
</p>
<!-- 2.3 forEach标签 -->
<!-- items:声明遍历的数据
var:给每次循环所获得的数据命名
-->
<p>
<c:forEach items="${stu.interests }" var="i">
${i }
</c:forEach>
</p>
<!-- 2.4 自定义标签 -->
<p><s:sysdate/></p>
<p><s:sysdate format="yyyy年MM月dd日"/></p>
</body>
</html>
![这里写图片描述](//img-blog.csdn.net/20180316171349373?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
s.tld(自定义标签)
<?xml version="1.0" encoding="UTF-8" ?>
<taglib xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1">
<description>这是我自己的标签库</description>
<display-name>Dany</display-name>
<tlib-version>3.1</tlib-version>
<short-name>s</short-name>
<uri>/dany_tags</uri>
<tag>
<description>用来输出服务器的时间</description>
<name>sysdate</name>
<tag-class>web.SysdateTag</tag-class>
<!-- 声明该标签可以包含哪些内容 -->
<body-content>empty</body-content>
<attribute>
<description>用来设置时间的格式</description>
<name>format</name>
<!-- 是否必须给这个属性赋值 -->
<required>false</required>
<!-- 是否可以用EL给此属性赋值 -->
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
</attribute>
</tag>
</taglib>
SysdateTag.java(用于自定义标签)
package web;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.SimpleTagSupport;
/**
* 自定义标签
* 1.编写java类,继承SimpleTagSupport
* 2.在doTag方法中添加处理逻辑
* 3.配置标签说明文件
*/
public class SysdateTag extends SimpleTagSupport {
private String format = "yyyy/MM/dd HH:mm:ss";
public String getFormat() {
return format;
}
public void setFormat(String format) {
this.format = format;
}
@Override
public void doTag() throws JspException, IOException {
//创建服务器时间
Date date = new Date();
//格式化时间
SimpleDateFormat sdf = new SimpleDateFormat(format);
String now = sdf.format(date);
//将时间输出给浏览器
//PageContext extends JspContext
//该方法声明返回JspContext,
//但在实现时返回的是PageContext。
//所以可以将其强转为PageContext,
//从而获取其他8个隐含对象。
PageContext ctx = (PageContext) getJspContext();
JspWriter out = ctx.getOut();
out.println(now);
//此处一定不能关闭流,因为其他的标签
//也要用这个流。
}
}
![这里写图片描述](//img-blog.csdn.net/20180316171454380?watermark/2/text/Ly9ibG9nLmNzZG4ubmV0L0RheWN5bQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70)
七、如何开发自定义标签(上个案例中有示例)
- 编写JAVA类,继承SimpleTagSupport类
- 在doTag方法中添加处理逻辑
- 配置标签说明文件