🐕
servlet 简介
Servlet(Servlet Applet),全称Java Servlert .是用Java编写的服务器端程序。其主要功能在与交互式的浏览和修改数据,生成动态Web内容。
狭义的servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet的类,一般情况下,人们将Servlet理解为后者。
比如HttpServlet类继承自Servlet类,可以利用继承Http Servlet 来实现Http请求,当不是Http请求的时候,也可以定义其他形式的Servlet。
Servlet 运行于支持Java的服务器中,从现实上讲,servlet 可以响应任何类型的请求,但是绝大多数情况下Servlet只用于来扩展基于THHP协议的Web服务器
注意:Servlet不是从命令行启动的,而是由包含Java虚拟机的Web服务器进行加载
Servlet是单实例多线程的。
servlet生命周期
在Servlet产生到消亡的过程中,有三个生命周期函数,通过javax.servlet.Servlet接口中初始化方法init(),处理客户请求的方法service(),终止方法destroy()来表示。
注意:创建Servlet实例、调用实例的init()和destroy()方法都只进行一次,当初始化完成后,Servlet容器会将该实例保存在内存中
servlet的生命周期包含以下4个阶段:
(1)加载和实例化
Servlet容器负责加载和实例化Servlet。当Servlet容器启动或客户端发送一个请求时,Servlet容器会查找内存中是否存在该Servlet实例,若存在,则直接读取该实例响应请求;如果不存在,就创建一个Servlet实例。
(2) 初始化
实例化后,Servlet容器将调用Servlet的init()方法进行初始化,初始化的目的是为了让Servlet对象在处理客户端请求前完成一些初始化的工作,
对于每一个Servlet实例,init()方法只被调用一次。(该方法执行在单线程的环境下,因此开发者不用考虑线程安全的问题。)在初始化期间,Servlet实例可以使用容器为它准备的ServletConfig对象从Web应用程序的配置信息(在web.xml中配置)中获取初始化的参数信息。在初始化期间,如果发生错误,Servlet实例可以抛出ServletException异常或者UnavailableException异常来通知容器。
ServletException异常用于指明一般的初始化失败,例如没有找到初始化参数;而UnavailableException异常用于通知容器该Servlet实例不可用。例如,数据库服务器没有启动,数据库连接无法建立,Servlet就可以抛出
UnavailableException异常向容器指出它暂时或永久不可用。。
(3)服务
初始化后,Servlet处于能响应请求的就绪状态。在service()方法中,
Servlet实例通过ServletRequest对象得到客户端的相关信息和请求信息,在对请求进行处理后(根据不同的请求 转调不同的doXxx()方法),调用ServletResponse对象的方法设置响应信息。在service()方法执行期间,如果发生错误,Servlet实例可以抛出ServletException异常或者UnavailableException异常。如果UnavailableException异常指示了该实
例永久不可用,Servlet容器将调用实例的destroy()方法,释放该实例。此后对该实例的任何请求,都将收到容器发送的HTTP 404(请求的资源不可用)响应。如果UnavailableException异常指示了该实例暂时不可用,那么在暂时不可用的时间段内,对该实例的任何请求,都将收到容器发送的HTTP 503(服务器暂时忙,不能处理请求)响应。
注意:为了提高效率,Servlet规范要求一个Servlet实例必须能够同时服务于多个客户端请求,即service()方法运行在多线程的环境下,开发者必须保证该方法的线程安全性。
(4)销毁
当Servlet容器关闭时,Servlet实例也随时销毁。其间,Servlet容器会调用Servlet 的destroy()方法去判断该Servlet是否应当被释放(或回收资源)。
servlet工作过程
1. 在客户端对web服务器发出请求
2. web服务器接收到请求后将其发送给Servlet
3. Servlet容器为此产生一个实例对象并调用ServletAPI中相应的方法来对客户端HTTP请求进行处理,然后将处理的响应结果返回给WEB服务器.
4. web服务器将从Servlet实例对象中收到的响应结构发送回客户端.
servlet使用
一、读取表单数据
输入框
Servlet 处理表单数据,这些数据会根据不同的情况使用不同的方法自动解析:
getParameter():您可以调用 request.getParameter() 方法来获取表单参数的值。
getParameterValues():如果参数出现一次以上,则调用该方法,并返回多个值,例如复选框。
getParameterNames():如果您想要得到当前请求中的所有参数的完整列表,则调用该方法。
复选框
使用getParameter,读取选取的选择框值位on,没选读取就是null.
读取表单所有的值
Enumeration paramNames = request.getParameterNames();
while(paramNames.hasMoreElements()) {
String paramName = (String)paramNames.nextElement();
String[] paramValues = request.getParameterValues(paramName);
// 读取单个值的数据
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() == 0)
out.println("<td><i>没有值</i></td>");
else
out.println("<td>" + paramValue + "</td>");
} else {
// 读取多个值的数据
out.println("<td><ul>");
for(int i=0; i < paramValues.length; i++) {
out.println("<li>" + paramValues[i]);
}
}
二、返回数据
response.getWriter().write("xxx");
三、get请求和post请求
GET方式提交
a)地址栏 (URL) 会跟上参数数据。以?开头,多个参数之间以&分割
b)GET方式提交参数,数据限制,不超过1kb。
c)GET方式不适合提交敏感数据 (如:密码)。
d)注意:浏览器直接访问请求,默认请求方式是get方式。
POST方式提交
a)参数不会跟在URI后面,而是跟在请求实体内容中。没有?开头、多个参数之间以&分割 如:
b)post方式提交参数,数据是没有限制的
c)适合提交敏感数据
四、转发和重定向
转发
方式:request.getRequestDispacther("/test.jsp").forword(request,response);
浏览器的请求发送给组件1,组件1经过一些处理之后,将request和response对象“传递”给组件2,由组件2继续处理,然后输出响应(当然,也可以继续向其他组件“传递”),这个传递的过程称之为“转发”。
转发过程:客户浏览器发送http请求—-》web服务器接受此请求–》调用内部的一个方法在容器内部完成请求处理和转发动作—-》将目标资源发送给客户。
整个过程只涉及一次浏览器和服务器之间的“请求-响应”,转发过程中的组件共享同一个请 求(request)和响应(response)对象。
转发的意义在于可以实现组件的“分工”。在基于MVC,多层结构的Web应用中,经常需要多个组件协同完成一次“请求-响应”工作。
重定向
方式:response.sendRedirect(“test.jsp”);
浏览器向某组件发出请求信息,组件向浏览器发回一个重定向响应信息,该响应信息不包含具体的数据内容,只是在响应头信息中包含了需要重定向到的地址信息,该地址可以是任何有效的URL。浏览器收到该重定向响应后会自动的向响应信息头中所指示的地址发出请求。整个重定向的过程涉及两次“请求-响应”。
重定向过程:客户浏览器发送http请求—-》web服务器接受后发送302状态码响应及对应新的location给客户浏览器–》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址—-》服务器根据此请求寻找资源并发送给客户。
转发和重定向的区别
1、安全性
显然 请求转发更安全。一个请求在完成的过程中可能会通过多个Servlet,最终到达一个jsp页面,在整个过程中,url是不会变的。这样从客户端就看不出来服务器是由哪些资源来处理数据的。
而重定向更遵循”所见即所得“,也就是你所请求的资源,就是url显示的。比如重定向到test.jsp,url可能就是“localhost:8080/project_name/test/test.jsp”.这样不仅不安全,也限制了服务器端的灵活性。
2、可定位范围
重定向范围更广,应该说它可以重定向到任何有效的url。
而转发就比较杯具了,只能在服务器内部转发。
五、web.XML配置
<!-- 配置一个servlet -->
<!-- servlet的配置 -->
<servlet>
<!-- servlet的内部名称,自定义。尽量有意义 -->
<servlet-name>ServletDemo</servlet-name>
<!-- servlet的类全名: 包名+简单类名 -->
<servlet-class>lm.practice.ServletDemo</servlet-class>
</servlet>
<!-- servlet的映射配置 -->
<servlet-mapping>
<!-- servlet的内部名称,一定要和上面的内部名称保持一致!! -->
<servlet-name>ServletDemo</servlet-name>
<!-- servlet的映射路径(访问servlet的名称) -->
<url-pattern>/servlet</url-pattern>
</servlet-mapping>
注意:
1)url-pattern要么以 / 开头,要么以*开头。 绝对不能漏掉斜杠!!!!!!!!!
2)不能同时使用两种模糊匹配,例如 /lm/*.do是非法路径
3)当有输入的URL有多个servlet同时被匹配的情况下:
3.1 精确匹配优先。(长的最像优先被匹配)
3.2 以后缀名结尾的模糊匹配先级最低!!!
请求参数的编码问题
(1)修改post方式参数的编码
Request.setCharacterEncoding(“utf-8”);
(2)修改get方式参数的编码(有多少个参数就写多少次;
或者直接修改Tomcat中配置文件[即在端口号那一行代码后面加上URLEncoding=“utf-8”;],不建议这样做)
String name=request.getParameter("name");
String names=new String(name.getBytes(“iso8859-1”),”utf-8”);
状态码:服务器处理请求的结果(状态)
常见的状态码
200:表示请求处理完成完美返回
302:表示请求需要进一步细化
404:表示客户访问的资源找不到(即找不到访问路径或者说路径错误)
500:表示服务器资源发送错误(服务器内部错误,即代码错误)