1、使用Servelet,可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态的创建网页。
2、servlet的生命周期定义为从创建到毁灭的过程,过程如下:
Servlet初始化后调用init()方法
Servlet调用service()方法来处理客户端的请求
Servelt销毁前调用dextriy()方法
最后由jvm的垃圾回收器进出回收
init方法只会被调用一次,他在第一次创建servlet的时候被调用,在后续每次用户请求时不在被调用,
public void init() throws ServletException {
// 初始
一个Servlet形如
service方法,是执行实际任务的主要方法,调用该方法来处理来自客户端(浏览器)的请求,并且格式化的响应写回给客户端。服务器收到servlet请求时,服务器会产生一个新的线程并且调用服务,该方法会检测http的请求类型(get、post、put、delete)并在合适的时候调用doget、dopost、doput等方法。
public void service(ServletRequest request,
ServletResponse response)
throws ServletException, IOException{
}
``
**注:service方法由服务器调用,我们不需要对该方法做任何操作,只需要根据请求类型来重写doGet或者doPost方法即可。
**
doGet方法,请求来自于URL的正常请求,或者来自于一个未指定method的html表单,由该方法处理
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}
doPost方法,请求来自于一个特别指定了method为POSt的html表单
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}
Fileter :在http请求到达servlet之前,可以被一个或多个Fiter预处理,例如打印日志,登陆检查等
@WebServlet(urlPatterns = “/hello”)
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
…
}
}
其中,@WebServlet(urlPatterns = "/hello")注解表示处理的路径;
**HttpServletRequest**
封装了一个http**请求**,实际上是从servletRequest继承而来,HttpServletRequest提供的接口方法可以拿到http请求的几乎全部信息,
- getMethod():返回请求方法,例如,"GET","POST";
getRequestURI():返回请求路径,但不包括请求参数,例如,"/hello";
getQueryString():返回请求参数,例如,"name=Bob&a=1&b=2";
getParameter(name):返回请求参数,GET请求从URL读取参数,POST请求从Body中读取参数;
getContentType():获取请求Body的类型,例如,"application/x-www-form-urlencoded";
getContextPath():获取当前Webapp挂载的路径,对于ROOT来说,总是返回空字符串"";
getCookies():返回请求携带的所有Cookie;
getHeader(name):获取指定的Header,对Header名称不区分大小写;
getHeaderNames():返回所有Header名称;
getInputStream():如果该请求带有HTTP
Body,该方法将打开一个输入流用于读取Body;
getReader():和getInputStream()类似,但打开的是Reader;
getRemoteAddr():返回客户端的IP地址;
getScheme():返回协议类型,例如,"http","https";
HttpServletRequest还有两个方法:setAttribute()和getAttribute(),可以给当前HttpServletRequest对象附加多个Key-Value,相当于把HttpServletRequest当作一个Map<String, Object>使用。
**HttpServletResponse**
HttpServletResponse封装了一个HTTP**响应**。由于HTTP响应必须先发送Header,再发送Body,所以,操作HttpServletResponse对象时,必须先调用设置Header的方法,最后调用发送Body的方法。
常用的设置Header的方法有:
- setStatus(sc):设置响应代码,默认是200;
setContentType(type):设置Body的类型,例如,"text/html";
setCharacterEncoding(charset):设置字符编码,例如,"UTF-8"; setHeader(name,
value):设置一个Header的值; addCookie(cookie):给响应添加一个Cookie; addHeader(name,
value):给响应添加一个Header,因为HTTP协议允许有多个相同的Header;
写入响应时,需要通过getOutputStream()获取写入流,或者通过getWriter()获取字符流,二者只能获取其中一个。
写入响应前,无需设置setContentLength(),因为底层服务器会根据写入的字节数自动设置,如果写入的数据量很小,实际上会先写入缓冲区,如果写入的数据量很大,服务器会自动采用Chunked编码让浏览器能识别数据结束符而不需要设置Content-Length头。
但是,写入完毕后调用flush()却是必须的,因为大部分Web服务器都基于HTTP/1.1协议,会复用TCP连接。如果没有调用flush(),将导致缓冲区的内容无法及时发送到客户端。此外,写入完毕后千万不要调用close(),原因同样是因为会复用TCP连接,如果关闭写入流,将关闭TCP连接,使得Web服务器无法复用此TCP连接
一个Servlet类在服务器中只有一个实例,但对于每个HTTP请求,Web服务器会使用多线程执行请求。因此,一个Servlet的doGet()、doPost()等处理请求的方法是多线程并发执行的。如果Servlet中定义了字段,要注意多线程并发访问的问题
//发送重定向响应:
resp.sendRedirect(redirectToUrl);
//转发
req.getRequestDispatcher("/hello").forward(req, resp);
Cookie,用于标识浏览器身份的id
Session,用于标识用户身份的唯一id,比如淘宝网,没有session技术,每次切换页面,都需要重新登陆。服务器识别Session的关键就是依靠一个名为JSESSIONID的Cookie,jsessionid是由servlet容器自动创建的,目的是为了维护一个浏览器会话,