[TOC]
Servlet是基于多线程的实现(CGI:是一项基于多进程的网络请求实现),Servlet的生命周期指的是一个Servlet从创建到销毁的整个过程:
HttpServletRequest
是servlet中的一个核心接口,用于处理客户端请求的接口对象,客户端发送的请求信息,包括cookie数据都存在于该对象中,常见方法:
String getParameter(String paramName)
:根据客户端的请求参数名称获取参数值String[] getParameterValues(String paramName)
:根据客户端的请求参数名获取所有参数值(数组)Map<String,String[]> getParameterMaps()
:将所有的请求参数和参数值获取为一个Map集合 Enumeration<String> getParameterNames()
:获取所有的请求参数的参数名Cookie[] getCookies()
:获取来自客户端传递的所有cookie信息String getHeader(String name)
:根据请求头的属性名获取属性值Enumeration<String> getHeaderNames()
:获取请求头的所有属性名String getMethod()
:获取客户端请求方式(get/post/...)setCharacterEncoding(String encoding)
:设置请求头的编码方式(通常使用post提交时需要设置为UTF-8
)String getQueryString()
:获取请求地址中的查询参数,一般针对get
请求String getRequestURI():
获取客户端的请求资源名称String getServletPath()
:获取请求的servlet地址HttpSession getSession()
:获取session对象ServletContext getServletContext()
:获取Servlet上下文对象(全局对象)setAttribute(String name,Object value)
:向请求范围内存储数据getAttribute(String name)
:根据属性名称获取属性值removeAttribute(String name)
:移除request范围内的属性对getSession()
:获取session对象paramName指的是请求地址栏中的参数名: http://127.0.0.1/user?`username=XXX&password=XXX` 也可以是表单中的控件名称:
<input type="text" name="username">
以上表单控件中的username
即为请求参数名
HttpServletResponse
是Servlet中的一个核心响应接口,用于对客户端请求处理完成之后做出响应的接口对象,可以通过该对象发送各种类型(MIME-Type)的响应信息到客户端中,并且也能够实现客户端请求的重定向(redirect),常见方法:
addCookie(Cookie c)
:将在服务端创建的cookie对象响应到客户端中
sendRedirect(String path)
:重定向到一个指定的资源中(页面或者另一个servlet)
sendError(int code,String msg)
:响应错误信息到客户端(状态码,消息)
setHeader(String name,String value)
:设置响应头信息
setContentType(String contentType)
:设置响应的内容类型:
response.setContentType("text/json;charset=utf-8")
setCharacterEncoding(String encoding)
:设置响应的编码类型
PrintWriter getWriter()
:获取一个字符输出流用于向客户端响应文本信息(常见json数据)
ServletOutputStream getOutputStream()
:获取基于response对象的字节输出流,一般用于文件传输等二进制数据响应
ServletConfig
是一个用于表示当前Servlet对象的配置接口,任何一个Servlet类都对应一个唯一的ServletConfig
,通关观察类的层次结构图能够发现,所有的Servlet最终都实现过该接口:
常见方法:
String getServletName()
:获取当前Servlet名称
String getInitParameter(String var1)
:获取指定的初始化参数
ServletContext getServletContext()
:获取servlet上下文环境
Enumeration<String> getInitParameterNames()
:获取所有的初始化参数名
初始化参数指的是servlet在配置时指定的参数信息,通常以参数名和参数值的结构存在,使用方法:
基于web.xml配置(推荐)
<servlet>
<servlet-name>GoodsServlet</servlet-name>
<servlet-class>com.softem.servlet.GoodsServlet</servlet-class>
<!-- 初始化参数-->
<init-param>
<param-name>suffix</param-name>
<param-value>.png,.jpg,.bmp,.jpeg</param-value>
</init-param>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>GoodsServlet</servlet-name>
<url-pattern>/goods</url-pattern>
</servlet-mapping>
基于注解的配置
@WebServlet(urlPatterns = "/goodsServlet",
initParams = {
@WebInitParam(name = "suffix",value = ".png,.jpg,.bmp,.jpeg")
})
public class GoodsServlet extends HttpServlet {
}
获取初始化参数:
在servlet的init方法中获取
public class GoodsServlet extends HttpServlet {
private String suffix;
@Override
public void init(ServletConfig config) throws ServletException {
//获取初始化参数
suffix = config.getInitParameter("suffix");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("初始化参数:"+suffix);
}
}
直接在Servlet的service或者doGet/doPost
方法中使用:
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String suffix = this.getInitParameter("suffix");
System.out.println("初始化参数:"+suffix);
System.out.println(this.getInitParameter("encoding"));
}
如果用上述方式获取初始化参数,则不能覆盖
GenaricServlet
中的init(ServletConfig config)
当客户端请求到达Servlet中,在Servlet中执行完相关的处理之后,接下来应该要向客户端响应数据(response.getWriter());Servlet除了响应之外应该还包含对于请求之后的响应跳转;
Servlet对于客户端请求之后的跳转包含两种形式:
请求转发也称之为服务端跳转,即客户端发送一次请求到服务器,服务器内部会进行一次或多次转发,并将结果返回给客户端,对于客户端来说只认为发送了一次请求,减少网络请求次数;并且使用请求转发,可以将存储在请求范围内(request.setAttribute(name,value))的数据传递到下一个Servlet中
请求转发是由
HttpServletRequest
发起的 //获取请求转发的对象,并将请求响应传递给下一个目标 req.getRequestDispatcher("list").forward(req,resp);
重定向也称之为客户端跳转,即客户端发送请求到服务端之后,服务端通过response.sendRedirect(path)
将请求地址返回到客户端,由客户端再发起下一次请求(与上一次请求无关),此时地址栏会变化为下一次请求的资源地址,由于下一次请求与上次无关,则存储在request
范围内的数据无法传递到下一个请求中:
重定向由
HttpServletResponse
对象发起 //重定向到下一个目标(告知客户端对另一个地址发起请求) resp.sendRedirect("list")
Http协议是无状态的,由于该特性的存在,在客户端向服务端发起多次请求时,每个请求之间没有任何关联关系,因此对于以上问题,Servlet中提供了四种方式用于实现会话跟踪;所谓会话(session)跟踪即需要实现请求之间的衔接性(在进行页面跳转时进行数据的传递),四种会话跟踪技术如下:
url传值是一种较为常见的会话跟踪技术,试下原理是:在请求地址栏中添加需要传递的数据,数据是以名值对的形式在地址栏拼接,然后在服务端通过request.getParamater()
等方法获取请求参数即可:
http://127.0.0.1/add?name=admin&sex=1&age=18
String name = request.getParamater("name");
String sex = request.getParamater("sex");
String age = request.getParamater("age");
表单提交(GET)也可以认为是一种URL传值的形式
通过表单控件input:hidden
实现数据的传递,隐藏域在页面是默认隐藏,但是可以通过给其设置name和value属性进行数据传递:
<form action="goods">
<!--隐藏域-->
<input type="hidden" name="method" value="del">
<button type="submit">跳转</button>
</form>
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
switch (method){
case "add":
add(req,resp);
break;
case "del":
del();
break;
}
}
session通常理解为一个会话:客户端对服务端请求的一整个生命周期(浏览器从打开到关闭的过程都位于一个session中);客户端一旦跟浏览器建立起连接都会产生一个session对象,session对象对于当前客户端是唯一的;session的存储位置在服务端
session的获取方式是通过HttpServletRequest
对象:
HttpSession session = request.getSession();
session = request.getSession(true);
request.getSession(boolean b):在使用该方法创建session时,如果传入参数为true时才会新建session,否则直接使用现有的session对象
向session中添加数据
//获取session
HttpSession session = req.getSession();
session.setAttribute("msg","session中的数据");
获取session中存储的数据
Object obj = req.getSession().getAttribute("msg");
移除session中的元素
req.getSession().removeAttribute("msg");
将session失效
req.getSession().invalidate();
安全退出,用户注销,清理缓存等功能
session的默认有效期是30分钟
(tomcat服务器默认设置):
<!-- ==================== Default Session Configuration ================= -->
<!-- You can set the default session timeout (in minutes) for all newly -->
<!-- created sessions by modifying the value below. -->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
可以通过修改项目的web.xml
设置默认的session有效时间
<!-- 设置session的超时时间(有效期)-->
<session-config>
<session-timeout>20</session-timeout>
</session-config>
注意事项: 由于每次重新开启浏览器访问服务端都会跟服务端建立起一个session,并且会生一个唯一的一个sessionID,例如:
3487B03DFD2A7055C92B155CBBD054E4
(JSESSIONID)因此,即便session的有效期未到,只要关闭浏览器并重新打开一个都会导致重新建立session(JSESSIONID会更新)
Cookie(曲奇),是一项用于在客户端浏览器存储数据的缓存技术,与session最大区别在于Cookie是基于浏览器的(客户端);每次客户端请求服务端时都会将cookie带入服务器,cookie中的数据存储形式是一种键值对结构,并且不允许直接出现特殊符号(通常需要通过http转码)
@WebServlet("/cookie")
public class CookieServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
switch (method){
case "put":
//添加cookie
add(req,resp);
break;
case "get":
//获取cookie
get(req,resp);
break;
}
}
/**
* 获取cookie
* @param req
* @param resp
*/
private void get(HttpServletRequest req, HttpServletResponse resp) {
Cookie[] cookies = req.getCookies();
for (Cookie c : cookies) {
String name = c.getName();
String value = c.getValue();
System.out.println(name+"--->"+value);
}
}
/**
* 添加cookie
* @param req
* @param resp
*/
private void add(HttpServletRequest req, HttpServletResponse resp) {
System.out.println("添加cookie.....");
//创建cookie对象
Cookie c = new Cookie("uid","10");
//设置cookie使用域
// c.setDomain("127.0.0.1");
//设置cookie的使用范围
c.setPath("/");
//设置cookie有效期(秒):默认有效期与session一致
c.setMaxAge(60*60*24);
//响应cookie到客户端
resp.addCookie(c);
}
}
session和cookie区别?