什么是jsp?
JSP全称Java Server Pages,是一种动态网页开发技术。它使用JSP标签在HTML网页中插入Java代码。标签通常以<%开头以%>结束。
JSP是一种Java servlet,主要用于实现Java web应用程序的用户界面部分。JSP通过网页表单获取用户输入数据、访问数据库及其他数据源,然后动态地创建网页。
JSP是Servlet的扩展,在没有JSP之前,就已经出现了Servlet技术。Servlet是利用输出流动态生成HTML页面,包括每一个HTML标签和每个在HTML页面中出现的内容。
为什么使用jsp?
性能更加优越,JSP可以直接在HTML网页中动态嵌入元素而不需要单独引用CGI文件。
服务器调用的是已经编译好的JSP文件,而不像CGI/Perl那样必须先载入解释器和目标脚本。
JSP 基于Java Servlet API,因此,JSP拥有各种强大的企业级Java API。
jsp处的位置
JSP处理流程
- 浏览器发送一个 HTTP 请求给服务器。
- Web 服务器识别出这是一个对 JSP 网页的请求,并且将该请求传递给 JSP 引擎。
- JSP 引擎从磁盘中载入 JSP 文件,然后将它们转化为 Servlet。
- JSP 引擎将 Servlet 编译成可执行类,并且将原始请求传递给 Servlet 引擎。
- Web 服务器的某组件将会调用 Servlet 引擎,然后载入并执行 Servlet 类。在执行过程中,Servlet 产生 HTML 格式的输出并将其内嵌于 HTTP response 中上交给 Web 服务器。
- Web 服务器以静态 HTML 网页的形式将 HTTP response 返回到浏览器中。
- Web 浏览器处理 HTTP response 中动态产生的HTML网页。
JSP生命周期
JSP生命周期就是从创建到销毁的整个过程,类似于servlet生命周期,区别在于JSP生命周期还包括将JSP文件编译成servlet.
-
JSP编译
当浏览器请求JSP页面时,JSP引擎会首先去检查是否需要编译这个文件。如果这个文件没有被编译过,或者在上次编译后被更改过,则编译这个JSP文件。
-
JSP初始化
容器载入JSP文件后,它会在为请求提供任何服务前调用jspInit()方法。如果您需要执行自定义的JSP初始化任务,重写jspInit()方法就行。
-
JSP执行
这一阶段描述了JSP生命周期中一切与请求相关的交互行为,直到被销毁。
当JSP网页完成初始化后,JSP引擎将会调用_jspService()方法。
void _jspService(HttpServletRequest request,HttpServletResponse response){ // Todo }
-
JSP销毁
JSP生命周期的销毁阶段描述了当一个JSP网页从容器中被移除时所发生的一切。jspDestroy()方法在JSP中等价于servlet中的销毁方法。当您需要执行任何清理工作时复写jspDestroy()方法。
public void jspDestroy(){ //清理 }
-
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> <%! //声明变量 private int initCnt = 0; private int serviceCnt = 0; private int destroyCnt = 0; %> <%! //初始化方法 public void jspInit(){ initCnt++; System.out.println("jspInit(): JSP被初始化了"+initCnt+"次"); } //销毁方法 public void jspDestroy(){ destroyCnt++; System.out.println("JSP被销毁了"+destroyCnt+"次"); } %> <% serviceCnt++; System.out.println("Jsp响应了"+serviceCnt+"次"); String initString="初始化次数 : "+initCnt; String serviceString="响应客户请求次数 : "+serviceCnt; String destroyString ="销毁次数 : "+destroyCnt; %> <h1>结果如下:</h1> <p><%= initString%></p> <p><%= serviceString%></p> <p><%= destroyString%></p> </body> </body> </html>
结果如下:(Tomcat 9.0 + jdk1.8)
初始化次数 : 1
响应客户请求次数 : 1
销毁次数 : 0
jsp相关语法:
1.<% %>叫做脚本片段,其中写的内容会翻译在Servlet的Service方法中,显然我们可以在Service方法中定义局部变量或者调用其他方法,但是不能在Service中再定义其他的方法,也就是我们可以在<%%>中定义局部变量或者调用方法,但不能定义方法。在jsp页面可以有多个脚本片段,但是多个脚本片段之间要保证结构完整。
2.<%!%>称作声明,其中写的内容将来会直接翻译在Servlet类中,因为我们可以在类中定义方法和属性以及全局变量,所以我们可以在<%!%>中声明方法、属性、全局变量。
3.<%=%>称作jsp表达式,用于将已经声明的变量或者表达式输出到网页上面。
4.直接写在jsp页面<body></body>中的代码称作模板元素,将来会Servlet的Service方法out.write("___")中,作为输出内容。
编写与其等价的XML语句<jsp:scriptlet>代码片段</jsp:scriptlet>。
<%-- jsp注释 --%>注释内容不会被发送至浏览器甚至不会被编译
<!-- 注释 --> HTML注释,通过浏览器查看网页源代码时可以看见注释内容
JSP指令
JSP指令用来设置与整个JSP页面相关的属性。
<%@ directive attribute="value" %> <%-- jsp指令语法格式 --%>
<%@ page …> | 定义页面的依赖属性,比如脚本语言、error页面、缓存需求等等 |
---|---|
<%@ include … %> | 包含其他文件 |
<%@ taglib … %> | 引入标签库的定义,可以是自定义标签 |
JSP行为
行为标签只有一种语法格式,它严格遵守XML标准:<jsp:action_name attribute=“value” />
JSP隐含对象
request对象
request对象是javax.servlet.http.HttpServletRequest 类的实例。每当客户端请求一个JSP页面时,JSP引擎就会制造一个新的request对象来代表这个请求。request对象提供了一系列方法来获取HTTP头信息,cookies,HTTP方法等等。
response对象
response对象是javax.servlet.http.HttpServletResponse类的实例。当服务器创建request对象时会同时创建用于响应这个客户端的response对象。
response对象也定义了处理HTTP头模块的接口。通过这个对象,开发者们可以添加新的cookies,时间戳,HTTP状态码等。
out对象
out对象是 javax.servlet.jsp.JspWriter 类的实例,用来在response对象中写入内容,用来输出boolean,char,int,double,String,object等类型数据。
application对象
application对象直接包装了servlet的ServletContext类的对象,是javax.servlet.ServletContext 类的实例。这个对象在JSP页面的整个生命周期中都代表着这个JSP页面。这个对象在JSP页面初始化时被创建,随着jspDestroy()方法的调用而被移除。通过向application中添加属性,则所有组成您web应用的JSP文件都能访问到这些属性。
pageContext 对象
pageContext对象是javax.servlet.jsp.PageContext 类的实例,用来代表整个JSP页面。
page对象
对象就是页面实例的引用。它可以被看做是整个JSP页面的代表。page 对象就是this对象的同义词。
HttpServletRequest类
request对象是javax.servlet.http.HttpServletRequest类的实例。每当客户端请求一个页面时,JSP引擎就会产生一个新的对象来代表这个请求。request对象提供了一系列方法来获取HTTP信息头,包括表单数据,cookies,HTTP方法等。
部分方法测试代码:
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Test Request Object</title>
</head>
<body>
<h1>HttpServletRequest</h1>
<p><% out.println("请求方式:"+request.getMethod()); %>></p>
<p><% out.println("编码方式:"+request.getCharacterEncoding()); %>></p>
<p><% out.println("request主体的MIME类型:"+request.getContentType()); %>></p>
<p><% out.println("与此request URL相关的路径:"+request.getPathInfo()); %>></p>
<p><% out.println("客户端的IP地址:"+request.getRemoteAddr()); %>></p>
<p><% out.println("request的URI:"+request.getRequestURI()); %>></p>
<p><% out.println("请求的servlet路径:"+request.getServletPath()); %>></p>
<p><% out.println("request是否使用了加密通道:"+request.isSecure()); %>></p>
<p><% out.println("request主体所包含的字节数:"+request.getContentLength()); %>></p>
<p><% out.println("服务器端口号:"+request.getServerPort()); %>></p>
</body>
</body>
</html>
HttpServletRequest(输出)
请求方式:GET >
编码方式:null >
request主体的MIME类型:null >
与此request URL相关的路径:null >
客户端的IP地址:0:0:0:0:0:0:0:1 >
request的URI:/ServletTest/requestDemo.jsp >
请求的servlet路径:/requestDemo.jsp >
request是否使用了加密通道:false >
request主体所包含的字节数:-1 >
服务器端口号:8080 >
HttpServletResponse类
esponse 对象是 javax.servlet.http.HttpServletResponse 类的一个实例。就像服务器会创建request对象一样,它也会创建一个客户端响应。response对象定义了处理创建HTTP信息头的接口。通过使用这个对象,开发者们可以添加新的cookie或时间戳,还有HTTP状态码。
部分方法测试代码:
<%@ 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>
<p>Response相关测试结果</p>
<p><%out.println("BufferSize:"+response.getBufferSize()); %>
<p><%out.println("CharacterEncoding:"+response.getCharacterEncoding()); %>
<p><%out.println("ContentType:"+response.getContentType()); %>
<p><%out.println("Status:"+response.getStatus()); %>
<%Cookie cookie = new Cookie("name","wanglj");%>
<br>
<%
response.addCookie(cookie);
Cookie[] cookies = request.getCookies();
if(cookies != null){
for(Cookie cook:cookies){
out.println("name:"+cook.getName());
out.println("value:"+cook.getValue());
out.print("<br>");
}
}
%>
</body>
</body>
</html>
Response相关测试结果
BufferSize:8192
CharacterEncoding:utf-8
ContentType:text/html;charset=utf-8
Status:200
name:JSESSIONID value:CA89C2AD98730B319F7C6475462679A1
name:name value:wanglj
HTTP状态码
JSP表单处理
我们在浏览网页的时候,经常需要向服务器提交信息,并让后台程序处理。浏览器中使用 GET 和 POST 方法向服务器提交数据。
GET 方法
GET方法将请求的编码信息添加在网址后面,网址与编码信息通过"?"号分隔。GET方法是浏览器默认传递参数的方法,一些敏感信息,如密码等建议不使用GET方法。用get时,传输数据的大小有限制 (注意不是参数的个数有限制),最大为1024字节。
POST方法
一些敏感信息,如密码等我们可以通过POST方法传递,POST提交数据是隐式的。JSP使用getParameter()来获得传递的参数,getInputStream()方法用来处理客户端的二进制数据流的请求。
JSP 读取表单数据
- getParameter(): 使用 request.getParameter() 方法来获取表单参数的值。
- getParameterValues(): 获得如checkbox类(名字相同,但值有多个)的数据。 接收数组变量 ,如checkbox类型。
- **getParameterNames()😗*该方法可以取得所有变量的名称,该方法返回一个 Enumeration。
- **getInputStream()😗*调用此方法来读取来自客户端的二进制数据流。
JSP过滤器
JSP 和 Servlet 中的过滤器都是 Java 类。过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。
JSP过滤器作用:
- 在客户端的请求访问后端资源之前,拦截这些请求。
- 在服务器的响应发送回客户端之前,处理这些响应。
各种类型的过滤器
- 身份验证过滤器(Authentication Filters)
- 数据压缩过滤器(Data compression Filters)
- 加密过滤器(Encryption Filters)
- 触发资源访问事件过滤器
- 图像转换过滤器(Image Conversion Filters)
- 日志记录和审核过滤器(Logging and Auditing Filters)
- MIME-TYPE 链过滤器(MIME-TYPE Chain Filters)
- 标记化过滤器(Tokenizing Filters)
- XSL/T 过滤器(XSL/T Filters),转换 XML 内容
过滤器通过 Web 部署描述符(web.xml)中的 XML 标签来声明,然后映射到您的应用程序的部署描述符中的 Servlet 名称或 URL 模式。
JSP Cookie
使用 JSP 设置 cookie(三步)
//Cookie只有一个带参构造器
Cookie cookie = new Cookie("key","value");
- 创建Cookie对象
- **设置有效期:**调用 setMaxAge() 函数表明 cookie 在多长时间(以秒为单位)内有效。
- **将 cookie 发送至 HTTP 响应头中:**调用 response.addCookie() 函数来向 HTTP 响应头中添加 cookie。
-
**getName()**返回 cookie 的名称,名称创建后将不能被修改。
-
**getValue()**获取cookie的值。
JSP文件上传
JSP 可以与 HTML form 标签一起使用,来允许用户上传文件到服务器。上传的文件可以是文本文件或图像文件或任何文档。
upload.jsp : 文件上传表单程序。
message.jsp : 上传成功后跳转页面。
UploadServlet.java : 上传处理的 Servlet。
需要引入的 jar 文件:cos.jar,commons-fileupload-1.3.2、commons-io-2.5.jar。(可在Apache下载)
upload.jsp
注意点:
- 表单 method 属性应该设置为 POST 方法,不能使用 GET 方法。
- 表单 enctype 属性应该设置为 multipart/form-data.
- 表单 action 属性应该设置为在后端服务器上处理文件上传的 Servlet 文件。下面的实例使用了 UploadServlet Servlet 来上传文件。
- @MultipartConfig //文件上传注解
代码:
<%@ 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 method="POST" enctype="multipart/form-data" action="upser">
文件: <input type="file" name="upfile"><br/> <br/>
<input type="submit" value="上传">
</form>
</body>
</body>
</html>
message.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>文件上传结果</title>
</head>
<body>
<center>
<h2>成功</h2>
</center>
</body>
</html>
UploadServlet.java
package com.wanglj.servlet;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
@WebServlet("/upser")
@MultipartConfig //文件上传
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@SuppressWarnings("deprecation")
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理中文
req.setCharacterEncoding("utf-8");
//文件上传
Part part = req.getPart("upfile");
//得到上传的文件名
String fileName = part.getSubmittedFileName();
//判断上传的文件是否为空
String path = getServletContext().getRealPath("/uplaod");
part.write(path+fileName);
req.getRequestDispatcher("message.jsp").forward(req, resp);
}
}
JSP日期处理
使用JSP最重要的优势之一,就是可以使用所有Java API.Date类是很常用的一个事件处理类。
Date类的两个构造器
Date( );//无参构造器
Date(long millisec);//带参构造器,参数表示从1970年1月1日凌晨至所要表示时间的毫秒数
显示当前日期:
<%@page import="org.apache.jasper.tagplugins.jstl.core.Out"%>
<%@page import="java.text.SimpleDateFormat"%>
<%@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>Index</title>
</head>
<body>
<h1>显示当前时间日期</h1>
<%
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM--dd HH-mm-ss");
out.println("<h2 align=\"center\">" + sdf.format(date) + "</h2>");
%>
</body>
</body>
</html>
JSP页面重定向
当需要将文档移动到一个新的位置时,就需要使用JSP重定向了
重定向实例:
<%@page import="java.io.IOException"%>
<%@ 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>
<%
String baidu = new String("https://www.baidu.com");
//重定向到百度response.sendRedirect(location)
try{
response.sendRedirect(baidu);
System.out.print("重定向成功");
}catch(IOException e){
e.printStackTrace();
}
%>
<--下面方式同样效果-->
<%--String site = "https://www.baidu.com" ;
response.setStatus(response.SC_MOVED_TEMPORARILY);
response.setHeader("Location", site);
--%>
</body>
</body>
</html>
JSP自动刷新
public void setIntHeader(String header, int headerValue),
这个方法通知浏览器在给定的时间后刷新,时间以秒为单位。
JSP自动刷新测试:
<%@page import="java.text.SimpleDateFormat"%>
<%@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>自动刷新实例</title>
</head>
<body>
<h1>
自动刷新测试
</h1>
<%
//当前时间
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss");
out.println("当前时间:"+sdf.format(date));
// 设置每隔5秒刷新一次
response.setIntHeader("Refresh", 5);
%>
</body>
</body>
</html>
[1]:本文仅供个人学习记录使用,如果错误,欢迎提出,谢谢