Servlet、Jsp
一、Servlet
1、什么是Servlet?
(1)由sun公司(被oracle公司收购)制定的一种用来扩展web服务器功能的组件规范。简单的讲就是一种用来开发动态Web的技术。
扩展web服务器功能:web服务器通常只能用来处理静态资源的请求。而使用servlet可以用来处理动态资源的请求,比如访问数据库并向浏览器返回数据。
组件规范:指的是符合一定规范,实现部分功能,并且需要部署到相应的容器里面才能运行的软件模块。
(2)servlet是一个组件,需要部署到相应的servlet容器中才能运行。
容器:指的是符合一定规范,提供组件的运行环境的程序。
比如 tomcat 就是一个容器,提供了servlet的运行环境。
2、基本概念
(1)Servlet 接收用户请求 HttpServletRequest,在doGet(),doPost(),service()中做相应的处理,并将回应HttpServletResponse反馈给用户。
(2)一个Servlet类只会有一个实例,在它初始化时调用init()方法,销毁时调用destroy()方法。
(3)Servlet 可以设置初始化参数,供Servlet内部使用,在web.xml中配置。
(4)一个Servlet可以设置多个URL访问。Servlet不是线程安全的。
3、生命周期
(1)实例化一个servlet对象。
容器调用servlet构造器,创建相应的对象servlet,request,response。
(2)初始化servlet对象。
Web容器加载Servlet并将其实例化后,Servlet生命周期开始,容器运行其init()方法进行Servlet的初始化。
(3)响应请求(就绪)。
请求到达时调用Servlet的service()方法,service()方法会根据需要调用与请求对应的doGet或doPost等方法。
(4)销毁。
当服务器关闭或项目被卸载时服务器会将Servlet实例销毁,此时会先调用Servlet的destroy()方法。
注:
init方法和destroy方法只会执行一次,但service方法客户端每次请求 Servlet 时都会执行。Servlet 中有时会用到一些需要初始化与销毁的资源,因此可以把初始化资源的代码放入init方法中,销毁资源的代码放入destroy方法中,这样就不需要每次处理客户端的请求都要初始化与销毁资源。
4、相关类与接口
(1)Servlet接口
package javax.servlet; import java.io.IOException; public interface Servlet { void init(ServletConfig var1) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException; String getServletInfo(); void destroy(); }
(2)GenericServlet抽象类
实现了Servlet接口中的部分方法(比如:init, destroy)
(3)HttpServlet抽象类
继承GenericServlet抽象类,实现了service方法。
5、请求方式(Get、Post)
(1)get请求。
a、哪些情况下会发送get请求。
直接在浏览器中输入某个地址。
点击链接。
表单默认提交方式。<form method="get">
b、特点:
get将表单中数据按照name=value的形式,添加到action 所指向的URL 后面,并且两者使用"?"连接,而各个变量之间使用"&"连接。其会将请求参数显示在浏览器的地址栏,不安全。
get传输的数据要受到URL长度限制(最大长度是 2048 个字符),只能提交少量数据。
(2)post请求。
a、哪些情况下发送post请求。
设置表单提交方式。<form method="post">
b、特点:
post是将表单中的数据放在HTTP协议的请求头或消息体中,传递到action所指向URL。其不会将请求参数显示在浏览器地址栏,相对安全。
post可以传输大量的数据,上传文件通常要使用post方式。
6、重定向(Redirect,地址栏会改变)
(1)什么是重定向?
重定向指的是服务器通知浏览器向一个新的地址发送请求。
注:
可以发送一个302状态码和一个Location消息头,(该消息头包含一个地址,此地址称为重定向地址)浏览器收到之后,立即向重定位地址发送请求。
(2)如何重定向?
response.sendRedirect(String url);
注:
此处url为重定向地址,可以是任意的。
重定向之前,容器会先清空response对象中保存的数据。
(3)重定向特点:
a、重定向地址是任意的。
b、重定向后,浏览器地址栏的地址会发生改变。
7、转发(Forward,地址栏不会改变)
(1)什么是转发?
一个web组件将一个未完成的处理,转发给另外一个web组件继续做。
常用情况:一个servlet将处理结果转交给另一个jsp来展现。(当然也可以直接在一个jsp文件中直接写相关处理代码,但不建议这么做)
注:
web组件指的是一个jsp或者servlet(不规范定义)
(2)如何转发?
step1:绑定数据到request,内部采用HashMap保存数据。 request.setAttribute(String name, Object obj); step2:获得转发器。 RequestDispatcher rd = request.getRequestDispatcher(String uri); step3:转发。 rd.forward(request, response); 比如(转发到success.jsp页面): request.getRequestDispatcher("success.jsp").forward(request, response); 获取数据: Object request.getAttribute(String name);
(3)转发特点:
a、转发之后,浏览器地址栏不变。
b、转发的目的地必须是同一个应用。
8、转发与重定向的区别
(1)能够共享request?
转发可以,重定向不行。
注:
容器收到请求后,会创建request与response对象,当响应发送完毕,会销毁这两个对象。所以重定向(跳转到另一个页面)不行。
(2)浏览器地址栏有无变化?
转发无变化,重定向有变化。
(3)目的地有无限制?
转发有限制(只在同一个应用中转发),重定向无限制(可以跳转到任意连接)。
(4)从效率来说
forward:高。
redirect:低。
二、JSP
1、什么是JSP?
JSP(Java Server Pages)是由sun公司制定的一种服务器端动态页面技术规范。
注:
虽然servlet也可以生成动态页面,但是过于平凡调用(out.println),且不易维护(比如修改页面就得修改java代码),所以sun公司制定了JSP规范。
jsp是一个以(.jsp)为后缀的文件,容器会将这个文件转换为一个对应的servlet并执行。
2、JSP与servlet的关系?
(1)Servlet是一个特殊的Java程序,它运行于服务器的JVM中,通过服务器的支持向浏览器提供显示内容。
(2)JSP本质上是Servlet的一种简易形式,JSP会被服务器处理成一个类似于Servlet的Java程序,可以简化页面内容的生成。
(3)Servlet和JSP最主要的不同点在于,Servlet的应用逻辑是在Java文件中,并且完全从表示层中的HTML分离开来。而JSP的情况是Java和HTML可以组合成一个扩展名为.jsp的文件。
(4)JSP侧重于视图,Servlet更侧重于控制逻辑,在MVC架构模式中,JSP适合充当视图(view)而Servlet适合充当控制器(controller)。
3、JSP内置对象
(1)request:封装客户端的请求,其中包含来自GET或POST请求的参数;
(2)response:封装服务器对客户端的响应;
(3)pageContext:通过该对象可以获取其他对象;
(4)session:封装用户会话的对象;
(5)application:封装服务器运行环境的对象;
(6)out:输出服务器响应的输出流对象;
(7)config:Web应用的配置对象;
(8)page:JSP页面本身(相当于Java程序中的this);
(9)exception:封装页面抛出异常的对象。
参考:
JSP九大内置对象,七大动作,三大指令 https://blog.csdn.net/qq_34337272/article/details/64310849
4、JSP动作
(1)jsp:include:
在页面被请求的时候引入一个文件,可以包含静态和动态页面。(此处与include指令有区别,include只能用于包含静态页面)
【格式:】
<jsp:include page="文件路径"/>
(2)jsp:useBean:
寻找或者实例化一个 JavaBean。
【格式:】 <jsp:useBean id="javaBean的名称" scope="有效范围" class="包名.类名"></jsp:useBean>
(3)jsp:setProperty:
设置 JavaBean 的属性。
【格式:】
<jsp:setProparty name="javaBean名称" proparty="属性名" param="参数名" />
(4)jsp:getProperty:
读取某个 JavaBean 的属性。
【格式:】
<jsp:getProparty name="bean的名称" proparty="属性名称"/>
(5)jsp:forward:
把请求转到一个新的页面。
【格式:】
<jsp:forword page="文件路径"/>
(6)jsp:plugin(不常用):
用来产生客户端浏览器的特别标签(object或embed),可以使用它来插入Applet或JavaBean。
【格式:】
<jsp:plugin type="applet" code="com.jspdev.ch3.MyApplet" codebass="." align="center" width="200" height="200"></jsp:plugin>
(7)jsp:param (不常用):
用于设置参数,不能单独使用,主要用在jsp:include、jsp:forword、jsp:plugin指令中。
5、JSP指令
(1)什么是指令?
通知容器在将jsp转为servlet时,做一些额外的处理,比如导包(import)。
(2)指令的格式:
<%@指令名 属性=值 %>
(3)page指令:
【常用属性:】 import:等价于 Java 中 import 语句,用于导包,多个包用逗号隔开。 pageEncoding:指定当前页面的编码,如果pageEncoding没有指定,那么默认为contentType的值;如果pageEncoding和contentType都没有指定,那么默认值为iso-8859-1 contentType:等同与调用response.setContentType(“text/html;charset=xxx”); 如果没有指定contentType属性,那么默认为pageEncoding的值; 如果contentType和pageEncoding都没有指定,那么默认值为iso-8859-1 errorPage:如果当前页面出现异常,那么跳转到errorPage指定的jsp页面。 isErrorPage属性:false(默认,缺省),当isErrorPage为true时,表示这是一个异常处理界面,可以使用隐含对象exception。若为false,则不行。 session属性,true(默认,缺省),当session为false时,不能使用session隐含对象。 language:当前JSP编译后的语言!默认为java。 【举例:】 <%@ page language="java" import="java.util.*, java.text.*" pageEncoding="UTF-8"%>
(4)include指令:
【属性:】
file:告诉容器,在将jsp文件转换为servlet类时,将file属性指定的文件的内容插入到该指令所在的位置。
【格式:】
<%@ include file=”文件相对 url 地址” %>
(5)taglib指令:
taglib指令是用来在当前jsp页面中导入第三方的标签库 (需要先把第三方标签库所需jar包放到类路径中)。
【属性:】
prefix:指定标签前缀,这个东西可以随意起名
uri:指定第三方标签库的uri(唯一标识)
【举例:】
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" % prefix="c" >
6、include指令include动作的区别
(1)include指令:
JSP可以通过include指令来包含其他文件。被包含的文件可以是JSP文件、HTML文件或文本文件,与JSP同时编译执行。
语法格式如下: <%@ include file="文件相对 url 地址" %>
(2)include动作:
<jsp:include>动作元素用来包含静态和动态的文件。该动作把指定文件插入正在生成的页面。
语法格式如下: <jsp:include page="相对 URL 地址"/>
7、Request对象相关方法(大概了解一下即可)
// 设置名字为var1的request 的参数值。 void setAttribute(String var1, Object var2); // 删除请求中的一个属性 void removeAttribute(String var1); // 返回 var1 指定的属性值 Object getAttribute(String var1); // 返回request 对象所有属性的名字集合,结果是一个枚举的实例。 Enumeration<String> getAttributeNames(); // 返回客户端的所有 Cookie 对象,结果是一个Cookie 数组 Cookie[] getCookies(); // 返回请求中的字符编码方式 String getCharacterEncoding(); // 获得HTTP协议定义的文件头信息 String getHeader(String var1); // 返回指定名字的request Header 的所有值,结果是一个枚举的实例 Enumeration<String> getHeaders(String var1); // 返回所有 request Header 的名字,结果是一个枚举的实例 Enumeration<String> getHeaderNames(); // 返回请求的输入流,用于获得请求中的数据 ServletInputStream getInputStream() throws IOException; // 获得客户端向服务器端传送数据的方法 String getMethod(); // 获得客户端传送给服务器端的有 name指定的参数值 String getParameter(String var1); // 获得客户端传送给服务器端的所有参数的名字,结果是一个枚举的实例 Enumeration<String> getParameterNames(); // 获得有name指定的参数的所有值 String[] getParameterValues(String var1); // 获取客户端向服务器端传送数据所依据的协议名称 String getProtocol(); // 获取发出请求字符串的客户端地址 String getRequestURI(); // 获取客户端的 IP 地址 String getRemoteAddr(); // 获取客户端的名字 String getRemoteHost(); // 返回和请求相关 Session HttpSession getSession(); // 获取服务器的名字 String getServerName(); // 获取客户端所请求的脚本文件的路径 String getServletPath(); // 获取服务器的端口号 int getServerPort();
8、request.getAttribute()和 request.getParameter()的区别
(1)值的获取:
request.getAttribute() 用于获取对象容器的数据值。
request.getParameter() 用于获取 Get、Post请求所传递的参数值。
(2)取得值得类型:
request.getAttribute() 返回的是Object,需进行转换。可用setAttribute()设置成任意对象,使用很灵活。
request.getParameter() 返回的是String,用于读取提交的表单中的值。(获取之后会根据实际需要转换为自己需要的相应类型,比如整型,日期类型啊等等)
9、JSP作用域
(1)page:
page代表与一个页面相关的对象和属性。
(2)request:
request代表与Web客户机发出的一个请求相关的对象和属性。一个请求可能跨越多个页面,涉及多个Web组件;需要在页面显示的临时数据可以置于此作用域。
(3)session:
session代表与某个用户与服务器建立的一次会话相关的对象和属性。跟某个用户相关的数据应该放在用户自己的session中。
(4)application:
application代表与整个Web应用程序相关的对象和属性,它实质上是跨越整个Web应用程序,包括多个页面、请求和会话的一个全局作用域。
10、JSP基本规则
(1)以 (.jsp) 为后缀的文件。
(2)若是html(css、js)等代码,直接写即可。
其最后被转换成out.println()输出。
注:
out.println()与out.write()的区别:
对于null值,out.println会直接输出null;
对于null值,out.write会将其转为空字符串输出。
(3)若是java代码。格式: <% java语句 %>
其最后被转换为去掉<%%>后的代码。
(4)若是jsp表达式。格式:<%=java表达式 %>
其最后被转换为out.println(java表达式).
例如:<%=new Date()%>, 相当于 out.printn(new Date());
(5)若是jsp声明。格式:<%!java语句(声明一个变量或一个方法)%>
其最后被转换为去掉<%!%>后的代码。
例如:
<%!
int i = 100;
int sum(int a, int b){
return a+b;
}
%>
相当于声明了一个属性(成员变量)以及一个方法。
(6)jsp注释。
<!--注释内容-->,如果注释内容为java代码,那么java代码会被执行。即浏览器代码(服务器返回的代码)中会有执行java代码后的数据,但浏览器不会显示。
<%--注释内容--%>,如果注释内容为java代码,那么java代码不会被执行。
三、JSTL
1、JSTL是什么?
JavaServer Pages Standard Tag Library,指的是jsp标准标签库。
apache开发的一套jsp标签,后来捐献给sun公司,sun公司将其命名为jstl。
2、如何使用jstl?
step1:将jstl相关的jar文件拷贝到WEB-INT\lib目录下。并Build Path。
step2:使用taglib指令导入相应的标签。
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
其中:
uri:是一个命名空间。
prefix是命名空间的前缀(或者为别名)。
3、if标签
【格式:】 <c:if test="" var="" scope=""></c:if> 相当于if(){} 其中 c指的是命名空间(namespace,为了区分同名元素而设置的一个字符串)。 当test属性(必须)值为true时,容器会执行标签体里的内容。且test属性可以由el表达式来计算。 var属性:指定一个绑定的名称。 scope属性:指定绑定的范围,值可以是page,request,session,application。
4、choose标签
【格式:】 <c:choose> <c:when test=""> </c:when> <c:when test=""> </c:when> <c:otherwise> </c:otherwise> </c:choose> when可以出现一次或多次,表示一个分支,相当于else if,当test为true时,执行该分支。 otherwise可以出现0次会1次(最多),表示最后一个else。 相当于: if(){ }else if(){ }else if(){ }else{ }
其余标签以后再补充。。。
四、状态管理(cookie与session)
1、什么是状态管理
将浏览器与Web服务器间的多次交互作为一个整体来处理,并且将多次交互所涉及的数据(即状态)保存下来,即为状态管理。
2、cookie
(1)什么是cookie?
服务器临时保存在浏览器端的少量数据。一般用来保存用户信息。
(2)工作原理?
当浏览器访问服务器时,服务器可以将少量数据以set-cookie消息头的方式发送给浏览器,浏览器会将这些数据临时保存下来。
当浏览器再次访问服务器时,浏览器会将之前保存的这些数据以cookie消息头的方式发送给服务器。
(3)添加cookie(服务器对浏览器的响应操作,发送set-cookie)
【服务器向客户端发送Cookie:】 Cookie c =new Cookie("name","value"); //创建Cookie c.setMaxAge(60*60*24); //设置最大时效,此处设置的最大时效为一天 response.addCookie(c); //把Cookie放入到HTTP响应中 setMaxAge(int seconds) 缺省此方法时,浏览器会把cookie保存在内存里。只要浏览器不关闭,cookie就一直存在。浏览器关闭后,cookie会被销毁。 注: seconds单位是秒, seconds > 0, 浏览器会将cookie保存在硬盘上。若超过指定时间,则cookie被删除。 seconds < 0,缺省值,cookie放在内存中。 seconds = 0,删除cookie。 比如:删除一个名称为“cart”的cookie. Cookie c = new Cookie("cart", ""); c.setMaxAge(0); response.addCookie(c); 若想对cookie修改,则发送一个同名的cookie即可。
(4)获取cookie
【服务器从客户端读取Cookie:】 String name ="name"; Cookie[] cookies = request.getCookies(); if(cookies != null){ for(int i = 0;i< cookies.length;i++){ Cookie cookie = cookies[i]; cookie.getValue(); } }
3、session(会话)
(1)什么是session?
服务器端为维护状态而创建的一个特殊的对象。
(2)工作原理
浏览器访问服务器时,服务器会创建一个session对象,该session对象有一个唯一的id(称为sessionId)。服务器会将sessionId以set-cookie的方式发送给浏览器。
浏览器再次访问服务器时,浏览器会将sessionId以cookie的方式发送给服务器,服务器再依据sessionId找到对应的session对象。
注:
Http协议是一种无状态协议,服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是Session。
(3)如何获得session对象?
方式一:
HttpSession s = request.getSession(true/false);
true:
先查看请求当中有没有sessionId,如果没有sessionId,则创建一个session对象。
如果有sessionId,则依据该sessionId查找相应的对象,如果找到了,则返回这个session对象,如果没有找到(超时),则创建一个新的session对象。
false:
先查看请求当中有没有sessionId,如果没有sessionId,则返回null。
如果有sessionId,则依据该sessionId查找相应的对象,如果找到了,则返回这个session对象,如果没有找到(超时),则返回null。
方式二:
HttpSession s = request.getSession();
等价于:
HttpSession s = request.getSession(true);
(4)session超时。
a)、什么是session超时?
服务器会将空闲时间过长的session对象删除。
b)、缺省的超时时间。
服务器缺省的时间限制一般为30分钟。
可在tomcat(容器)文件夹中的conf文件夹,找到web.xml并设置,单位为分钟(不建议修改)。
c)、setMaxInActiveInterval(int seconds) //设置超时时间。
(5)session验证:
登录成功后,将一会数据绑定到session对象上。
比如:
session.setAttribute("user", user);
对于需要保护的资源,(比如success.jsp),添加session验证代码。
【比如:】 Object obj = session.getAttribute("user"); if(obj == null){ response.sendRedirect("login.jsp"); }
(6)session小结:
a)、相对于cookie,session的优点是安全的,可以保存大量数据,可以保存的数据类型更丰富。
b)、cookie是将状态(数据)保存在浏览器端,而session保存在服务器端,如果访问量大,使用session机制会占用大量的内存空间。