JSP介绍
JSP全称是Java Servlet Pages,它和servlet技术一样,都是SUN公司定义的一种开发动态web资源的技术。
特点:
- JSP是一种服务器端脚本语言,其出现降低了Servlet编写页面的难度。JSP本质上就是Servlet,实际上JSP是首先被翻译成Servlet后才编译运行的,因此JSP能够实现Servlet所能够实现的所有功能。
- 相比html而言,html只能为用户提供静态数据,而Jsp技术允许在页面中嵌套java代码,为用户提供动态数据。
JSP事例
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>第一个jsp</title>
</head>
<body>
<p>这是第一个jsp文件</p>
</body>
</html>
JSP运行原理
JSP同Servlet一样,都运行在Servlet容器中。当用户第一次访问JSP页面时,JSP页面的处理过程:
如果同一个JSP页面再次被请求时,只要没改变过jsp文件,容器直接调用已装载的字节码文件,省略翻译和编译的过程。
如果发生了修改,则重复上图过程。
JSP有三种类型元素
脚本元素
脚本元素的作用是添加Java代码到JSP页面中,脚本元素在页面被请求时执行。
脚本元素包括:脚本<% Java代码%>、表达式<%=表达式%>、声明<%! JSP声明%>和注释<%-- 注释--%>。
<%@page import="java.util.Calendar"%><%--指令元素 --%>
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>第一个jsp</title>
</head>
<body>
<p>这是第一个jsp文件</p>
<%--jsp脚本 --%>
<%if(Calendar.getInstance().get(Calendar.AM_PM)==Calendar.AM) {%>
现在是上午
<%}else {%>
现在是下午
<%} %>
<%--jsp表达式 --%>
现在时间:<%=new Date().toLocaleString() %>
</body>
</html>
JSP指令元素
JSP指令(directive)是为JSP引擎(Servlet容器)而设计的,它们并不直接产生任何可见输出,而只是告诉引擎如何处理JSP页面中的其余部分。
例如,上面例子中的<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
就规定了页面所用的语言。
pageEncoding:告诉tomcat服务器使用什么编码翻译jsp文件(jsp->java文件)
contentType:tomcat服务器发送给浏览器的数据编码(tomcat服务器->浏览器)
JSP指令元素包括三种:page指令、include指令、taglib指令
page指令
- <%@page %>
- 描述了和页面相关的信息,导入所需类包、指明输出内容类型、控制Session等
- page指令一般位于JSP页面的开头部分,
- 在一个JSP页面中,page指令可以出现多次,但是在每个page指令中,每一种属性却只能出现一次,重复的属性设置将覆盖掉先前的设置。
include指令
- include指令的作用是在页面翻译期间引入另一个文件,被包含的文件可以是JSP、HTML或文本文件。
- 语法:<%@includefile="文件"%>
<%@page import="java.util.Calendar"%><%--指令元素 --%>
<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>第一个jsp</title>
</head>
<body>
<p>这是第一个jsp文件</p>
<%@ include file="jspscript.jsp" %>
</body>
</html>
jspscript.jsp
<%@page import="java.util.Date"%>
<%@page import="java.util.Calendar"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<% if(Calendar.getInstance().get(Calendar.AM_PM)==Calendar.AM){%>
现在是上午
<% }else{%>
现在是下午
<% }%>
<br>
<%-- 这是jsp表达式 --%>
<%=new Date().toLocaleString()%>
<%! int age=20; %>
<%! public void setAge(int age){
this.age = age;
}%>
<% age=30; %>
<%-- age=age+5; --%>
age=<%=age %>
<%!public int sum(int a,int b){
return a+b;
}%>
<br>
2+3=<%=sum(2,3) %>
<%! %>
效果:
taglib指令用于页面加载某个标签库
- <%@tagliburi="标签库URI"prefix="标签前缀"%>
JSP动作元素
JSP规范定义了一系列标准动作,常用有下列几种:
- <jsp:include>标签
- <jsp:forward>标签
- <jsp:param>标签
<jsp:include>标签
- 用于在页面运行时引入一个静态或动态的页面,也称为动态包含。
- <jsp:include>如果包含的文件是普通的文本文件,就将文件的内容发送到客户端,由客户端负责显示;如果包含的文件是JSP文件,JSP容器就执行这个文件,然后将执行结果发送到客户端,由客户端负责显示这些结果。
- 语法:<jsp:includepage="relativeURL"flush="true|false"/>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>includeaction</title>
</head>
<body>
<jsp:include page="jspscript.jsp"></jsp:include>
</body>
</html>
效果
<jsp:forwad>标签
- 用于在页面运行时引入一个静态或动态的页面,也称为动态包含。
- <jsp:include>如果包含的文件是普通的文本文件,就将文件的内容发送到客户端,由客户端负责显示;如果包含的文件是JSP文件,JSP容器就执行这个文件,然后将执行结果发送到客户端,由客户端负责显示这些结果。
forwad.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>forwad</title>
</head>
<body>
<jsp:forward page="Servlet">
<jsp:param value="root" name="user"/>
<jsp:param value="root" name="pwd"/>
</jsp:forward>
</body>
</html>
Servlet.java
package cn.sdut.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/Servlet")
public class Servlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String name = request.getParameter("user");
System.out.println(name);
response.getWriter().write("欢迎你,"+name);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
效果:
+
注意:jsp中不能加注释,否则会报错
例如
<jsp:forward page="Servlet">
<%-- this --%>
<jsp:param value="root" name="user"/>
<jsp:param value="root" name="pwd"/>
</jsp:forward>
JSP内置对象
- JSP内置对象是指在JSP页面中,不用声明就可以在脚本和表达式中直接使用的对象。
- JSP内置对象也称隐含对象,它提供了Web开发常用的功能,为了提高开发效率,JSP规范预定义了内置对象。
JSP规范定义了9种内置对象
事例
Servlet
package cn.sdut.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
@WebServlet("/Servlet")
public class Servlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// String name = request.getParameter("user");
HttpSession session = request.getSession(false);
String name = (String) session.getAttribute("user");
System.out.println(name);
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("欢迎你,"+name);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
forwad.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>forwad</title>
</head>
<body>
<jsp:forward page="innerobject.jsp">
<jsp:param value="root" name="user"/>
<jsp:param value="root" name="pwd"/>
</jsp:forward>
</body>
</html>
innerobject.jsp
<%@ 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>
</head>
<body>
<!-- out对象 -->
<% out.print("hello,world"); %>
<%
//使用内置对象request获取参数
String name = request.getParameter("user");
//将内置对象存入session域中
session.setAttribute("user", name);
response.sendRedirect("Servlet");
%>
</body>
</html>
效果:
JSP的四种作用域
四种作用域的生命周期和可访问性介绍如下:
- 页面域(pagescope),存储在页面域的对象只对于它所在页面是可访问的。
- 请求域(requestscope),请求域的生命周期是指一次请求过程,包括请求被转发(forward)或者被包含(include)的情况。存储在请求域中的对象只有在此次请求过程中才可以被访问。
- 会话域(sessionscope),会话域的生命周期是指某个客户端与服务器所连接的时间,存储在会话域中的对象在整个会话期间(可能包含多次请求)都可以被访问。
- 应用域(applicationscope),应用域的生命周期是指从服务器开始执行服务到服务器关闭为止,是四个作用域中时间最长的。存储在应用域中的对象在整个应用程序运行期间可以被所有JSP和Servlet共享访问,在使用时要特别注意存储数据的大小和安全性,否则可能会造成服务器负载过重和线程安全性问题。
Servlet+JSP模式
- jsp负责显示页面及数据,即View。
- Servlet负责业务逻辑,如查阅数据,将返回的数据请求转发或者重定向给JSP显示。
例一:模拟一个用户登录功能,用户登录页面login.jsp,loginValidate.jsp实现对login.jsp的登录信息进行验证,如果验证失败,跳转回到login.jsp页面中进行显示提醒,登录信息验证成功时重定向到用户主页面main.jsp
login.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录页面</title>
</head>
<body>
<form action="loginValidate.jsp" method="post">
用户名:<input type="text" name="user">
密码:<input type="password" name="pwd">
<input type="submit" value="登录">
</form>
</body>
</html>
loginValidate.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>登录验证</title>
</head>
<body>
<%
String name = request.getParameter("user");
String pwd = request.getParameter("pwd");
boolean flag = false;
if(name.equals(""))out.print("用户名不能为空!");
if(pwd.equals(""))out.print("密码不能为空!");
if(pwd.length()<6||pwd.length()>12)out.print("密码在6-12位之间");
if(name.equals(pwd)&&pwd.length()>=6&&pwd.length()<=12){
flag = true;
session.setAttribute("name", name);
session.setAttribute("pwd", pwd);
}
%>
<%--如果验证通过,跳转到主界面,否则包含login.jsp文件 --%>
<%if(flag) {%><jsp:forward page="main.jsp"></jsp:forward>
<%} else%>
<jsp:include page="login.jsp"></jsp:include>
</body>
</html>
main.jsp
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>主界面</title>
</head>
<body>
登录成功!<br>
欢迎你,<%=session.getAttribute("name") %><br>
<%session.invalidate(); %><%--清除session --%>
<input type="button" value="退出" onclick="window.location.href='login.jsp'"><%--跳转到登录界面 --%>
</body>
</html>
例二:使用应用域实现留言板功能
<%@page import="java.util.Vector"%>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>留言板</title>
<script type="text/javascript">
function validate() {
String username = document.getElementId("username");
String message = document.getElementId("message");
if(username==""){
alert("请输入你的名字!");
username.focus();
return false;
}
esle if(message==""){
alert("请输入你的名字!");
message.focus();
return false;
}
return true;
}
</script>
</head>
<body>
<form action="leftmessage.jsp" method="post" onsubmit="return validate();" >
你的名字:<input type="text" id="username" name="username"><br>
输入你的留言:<textarea rows="10" cols="30" id="message" name="message"></textarea><br>
<input type="submit" value="提交你的留言">
</form>
<hr>
<%
String name = request.getParameter("username");
String message = request.getParameter("message");
//获得留言板留言
Vector<String> list = (Vector<String>)application.getAttribute("messageboard");
if(list==null){
list = new Vector<String>();
}
if(name!=null&&message!=null){
String info = name+"#"+message;
list.add(info);
application.setAttribute("messageboard", list);
}
if(list.size()>0){
for(String s:list){
String[] str = s.split("#");
out.print("<p>姓名"+str[0]+"<br>留言:"+ str[1]+"</p>");
}
}else{
out.print("还没有留言");
}
%>
</body>
</html>