一、 Introduction
Servlet的主要工作是对请求的处理和响应处理结果。具体是通过get或者post方法中的request和response对象完成。B/S架构中,客户端浏览器通过get或者post方法向服务端发起请求前提是遵循http协议,http协议中主要是关于请求和响应的协议。Servlet的request和response对象正是依据http的协议设计和执行。Request对象用于处理用户的请求,response用于向用户响应数据。
二、 Request
Servlet的service方法中doGet和doPost方法,将HttpServletReqeust接口的对象,即request作为参数传入使用。其中常用的方法有:
获得请求的方式(get还是post)、获得请求资源、获得协议类型、获得IP地址、获得端口号、获得请求头信息
1. Method
getAuthType() | |
getContextPath() | |
Cookie[] | getCookies() |
long | getDateHeader(String name) |
getHeader(String name) | |
getHeaderNames() | |
getHeaders(String name) | |
int | getIntHeader(String name) |
getMethod() | |
getPathInfo() | |
getPathTranslated() | |
getQueryString() | |
getRemoteUser() | |
getRequestedSessionId() | |
getRequestURI() | |
getRequestURL() | |
getServletPath() | |
getSession() | |
getSession(boolean create) | |
getUserPrincipal() | |
boolean | isRequestedSessionIdFromCookie() |
boolean | isRequestedSessionIdFromUrl() |
boolean | isRequestedSessionIdFromURL() |
boolean | isRequestedSessionIdValid() |
boolean | isUserInRole(String role) |
2. 关于获得请求行信息
protected voiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)throwsServletException, IOException {
String method=request.getMethod();
String uri=request.getRequestURI();
String protocol=request.getProtocol();
String ip=request.getRemoteAddr();
int port=request.getRemotePort();
System.out.println(method+"--"+uri+"--"+ip+"--"+port+"--"+protocol);
}
3. 关于获得请求头信息
在请求头信息中,有一个referer参数,这个表示请求源的引用路径。引用路径,说白了就是请求通过什么路径连接到服务器的。如果不是通过点击或者form表单形式的请求,也就是说通过地址栏输入地址的方式的请求,那么这个referer的值为空。这个参数可以用于防盗链设置。方法即判断请求源的引用路径是否不为空且等于特定全路径。
protected voiddoGet(HttpServletRequest request, HttpServletResponseresponse) throwsServletException, IOException {
//获得请求头信息
//获得请求主机和端口号
String host=request.getHeader("Host");
//获得用户代理
String userAgent=request.getHeader("User-Agent");
//获得cookies
String cookie=request.getHeader("Cookie");
System.out.println(host+"--"+userAgent+"--"+cookie);
//获得请求源的url引用
String referer=request.getHeader("referer");
System.out.println(referer);
}
4. 关于请求乱码
1) Get方式请求的乱码
先采用来源的编码来编码,再采用使用方的编码来解码。
如:浏览器采用的utf-8编码,而生产环境采用gbk编码
Stringusername=request.getParameter(“username”);
这时,得到的username是将utf-8编码的数据,采用gbk解码了,所以,需要先采用gbk编码,再采用utf-8解码,就可以得到信息原来的编码的内容。
username=newString(username.getBytes(“ISO-8859-1”) “utf-8”);
2) Post方式请求的乱码
请在获取请求参数之前,设置,比如网页为utf-8编码环境下:
request.setCharacterEncoding(“utf-8”);
3) 顺便介绍响应乱码的处理
response.setContentType("text/html;charset=UTF-8");
5. 获取请求参数
通过form表单,获取text类型的请求时,使用getParameter()方法。如果需要获得checkbox类型的参数,由于是多个参数的情况,需要使用getParameterValues()方法,而getParameterMap()方法一般用于BeanUtils类中获取form表单的全部参数的映射对并放入javabean。
例子:
protected voiddoGet(HttpServletRequest request, HttpServletResponseresponse) throwsServletException, IOException {
String username=request.getParameter("username");
String[] hobbies=request.getParameterValues("hobby");
System.out.println(username);
for(Stringhobby:hobbies){
System.out.println(hobby);
}
}
6. 请求转发
如果客户端发送到servlet的请求,需要根据情况,将请求流转交给另一个servlet处理,就产生了请求转发的需求。同一个请求流的转发可以多次进行,最后的servlet将处理结果响应给客户端。由于一次请求的生命周期,是请求发出和响应完成,所以,在请求转发过程中,需要保持请求流的唯一性和延续性,相当于,在请求的生命周期中,request可以作为一个容器,存放请求的数据,响应完成,则request容器清空。每次产生请求,则request容器再次存放相应的请求数据。
void | removeAttribute(String name) |
void | setAttribute(String name,Object o) |
getAttribute(String name) | |
getAttributeNames() |
例子:
protected voiddoGet(HttpServletRequest request, HttpServletResponseresponse) throwsServletException, IOException {
request.setAttribute("request","来自第一个servlet的转发请求");
//由于请求是在项目工程内执行,所有转发路径不需要写项目地址名
RequestDispatcher requestDispatcher=request.getRequestDispatcher("/Request2");
//forward根据新地址转寄,就是将这个servlet的request对象和response对象转寄给目标servlet
requestDispatcher.forward(request,response);
}
protected voiddoGet(HttpServletRequest request, HttpServletResponseresponse) throwsServletException, IOException {
//使用request,获得request中的属性内容
String requestContent=(String)request.getAttribute("request");
System.out.println(requestContent);
//将数据响应给客户端
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("来自servlet2的响应");
}
关于请求转发语句的链式简写方式:
request.getRequestDispatcher("/Request2").forward(request,response);
三、 Response
Servlet的service方法中doGet和doPost方法,将HttpServletResponse接口的对象,即response作为参数传入使用。主要用于实现向客户端发送响应的功能。
void | addCookie(Cookie cookie) |
void | addDateHeader(String name, long date) |
void | addHeader(String name,String value) |
void | addIntHeader(String name, int value) |
boolean | containsHeader(String name) |
encodeRedirectUrl(String url) | |
encodeRedirectURL(String url) | |
encodeUrl(String url) | |
encodeURL(String url) | |
void | sendError(int sc) |
void | sendError(int sc,String msg) |
void | sendRedirect(String location) |
void | setDateHeader(String name, long date) |
void | setHeader(String name,String value) |
void | setIntHeader(String name, int value) |
void | setStatus(int sc) |
void | setStatus(int sc,String sm) |
1. 请求的重定向
对于用户请求,如果本servlet不能满足这个请求或者不方便满足这个请求,可以采用重定向,即直接响应给用户,要求用户再次发起请求到指定的servlet或者视图页面。
一般,重定向的实现步骤:1,响应给用户302状态码;2,设置新的被请求路径。
例子:
protected voiddoGet(HttpServletRequest request, HttpServletResponseresponse) throwsServletException, IOException {
//设置需要用户重定向请求的状态码
response.setStatus(302);
//设置响应头头信息,指定用户重新请求的地址路径。注意:由于重定向可以指向任何内容,包括本项目外内容,所有路径中需要包括具体的项目路径名
response.setHeader("location","/servlet/Response2");
}
另外,上述步骤可以合并。关于合并重定向语句的简写方式:
response.sendRedirect("/servlet/Response2");
2. 设置定时刷新
使用响应头中的refresh参数,设置定时跳转到重定向的路径。
//定时刷新的时间单位为秒,实际时间受到网络速度影响。
response.setHeader("refresh","5,/servlet/Response2");
3. 响应乱码的处理
见上述请求乱码的处理。