Request介绍及演示样例 PART1
Request在ServletAPI的规范连接地址http://blog.csdn.net/zghwaicsdn/article/details/51035146
HTTP简介
URL是浏览器寻找信息时所须要的资源位置。通过URL。人类和应用程序才干找到、使用并共享因特网上大量的数据资源。
URL语法通过格式:
<scheme>://<user>:<password>@<host>:<port>/<path>;<params>?
<query>#<frag>
差点儿没有那个URL中包括了全部这些组件。
URL最重要的3个部分是方案(scheme)、主机(host)和路径(path).
经常使用介绍
方案 scheme:訪问server以获取资源时要使用那种协议
主机 host:资源宿主server的主机名或点分IP地址
port prot:资源宿主server正在监听的port号。非常多方案都有默认port号(HTTP的默认port号为80)
路径 path:server上资源的本定名,有一个斜杠将其与前面的URL组件分隔开来。
路径组件的语法是与server和方案有关的。
查询 query:某些方案会用这个组件传递參数以激活应用程序(如数据库、公告板、搜索引擎以及其它互联网网关),查询组件的内容没有通用格式。
用字符?将其与URL的器与部分分隔开来。
片段 frag:一小片或一部分资源的名字,引用对象时,不会将frag字段传递给server,这个字段是在client内部使用的。通过字符“#”将其与URL的器与部分分隔开来。
1.方案--使用什么协议
方案实际上是规定怎样訪问制定资源的主要标识符,它会告诉负责解析URL的应用程序应该使用什么协议。
方案组件必须以一个字母符号開始。有第一个“:”符号将其与URL的其余部分分隔开来。方案名是大写和小写无关的。
2.主机与port号
要想在因特网上找到资源。应用程序要知道是那台即其装载了资源。以及在那台机器的什么地方能够找到能对目标资源进行訪问的server。
主机组件表示了因特网上可以訪问资源的宿主机器。可以使用主机名或IP地址来表示主机名。
port组件标识了server正在监听的网络port。对下层使用TCP协议的Http来说。默认port号为80。
3.路径
URL的路径组件说明了资源位于server的什么地方。
路径通常非常像一个分级的文件系统路径。
4.查询字符串
通过提问题或者查询来缩小所请求资源类型的范围。
查询字符串以一系列“名/值”对的形式出现。名值对之间用字符“&”分隔
http报文
http是因特网的信使,那么HTTP报文就是它用来搬东西的包裹。
HTTP报文是在HTTP应用程序之间发送的数据块。这些数据块以一些文本形式元信息开头。这些信息描写叙述了报文的内容及含义,后面跟着可选的数据部分。
这些报文在client、server和代理之间流动。
HTTP使用流入和流出来描写叙述是无处理的方向。
报文向下游流动
HTTP报文会像河水一样流动。无论是请求报文还是响应报文,全部报文都会向下游流动。全部报文的发送者都在接受者的上游。
报文的组成部分
HTTP报文是简单的格式化数据块。
每条报文都包括一条来自client的请求。或者一条来自server的响应。
三部分组成:
1.对报文进行描写叙述的起始行(start line)
2.包括属性的首部块(header)
3.可选的、包括数据的主题部分(body)
由一个回车符和一个换行符分隔
请求报文的格式
<method> <request-URL> <version>
<headers>
<entiry-body>
响应报文的格式
<version> <status> <reason-phrase>
<headers>
<entiry-body>
简要描写叙述:
方法(method)
client希望server对资源运行的动作。
是一个单独的词,比方GET、HEAD或POST。
请求URL(request-URL)
命名了所请求资源。或者URL路径组件的完整URL。假设直接与server进行对化,仅仅要URL的路径组件是资源的绝对路径。
通常就不会有什么问题--server能够假定自己是URL的主机/port
版本号(version)
报文所使用的HTTP版本号,其格式看起来是这种:
HTTP/<major>.<minor>
当中主要版本(major)和次要版本(minor)都是整数。
状态码(status-code)
这三位数字描写叙述了请求过程中所发生的情况。每一个请求状态码的第一位数字都用于描写叙述状态的一般类别。
原因短语(reason-phrase)
数字状态码的可读版本号。包括行终止序列之前的全部文本。
首部(header)
能够有零个或多个首部。每一个首部都包括一个名字,后面跟着一个冒号(:),然后是一个可选的空格。接着是一个值。最后时一个CRLF。
首部是由一个空行(CRLF)结束的,表示了首部列表的结束和实体主题部分的開始。
实体的主题部分(entity-body)
实体的主题部分包括一个由随意数据组成的数据块。并非全部的报文都包括实体的主题部分。有时,报文仅仅是一个CRLF结束。
起始行
全部的HTTP报文都以一个起始行作为開始。
请求报文的起始行说明了要做些什么。响应报文的起始行说明发生了什么。
请求行
请求报文请求server对资源进行一些操作。请求报文的起始行,或称为请求行,包括了一个方法和一个请求URL,这种方法描写叙述了server应该运行的操作,
请求URL描写叙述了要对那个资源运行这种方法。
请求行中还包括HTTP的版本号,用来告知server,client使用的是哪种HTTP。
请求首部
请求首部仅仅在请求报文中有意义的首部。用于说明是谁或什么在发送请求、请求源来自何处,或者client的喜好及能力。
server能够依据请求首部给出的client信息。
试着为client提供更好的响应。
Request请求參数的编码问题
1.POST方法请求编码处理
假设client没有在Content-type标头中设置字符编码信息(比如浏览器能够设置Content-Type:text/html;charset=UTF-8),此时使用HttpServletRequest的
getCharachterEncoding()返回值是null。
在这个情况下,容器若使用的默认编码处理是ISO-8859-1,而client使用UTF-8发送非ASCII字符的请求參数。Servlet直接
使用getParameter()等方法取得该请求參数值,就会是不对的结果也就是得到乱码。
能够使用HttpServletRequest的setCharacterEncoding()方法指定取得POST请求參数时使用的编码。
request.setCharacterEncoding("UTF-8");
//解码
相当于要求容器作这个操作:String text = java.net.URLDecoder.decode("要转码的參数","UTF-8");
//编码
String text = java.net.URLDecoder.decode("原始字符","ISO-8859-1");
一定要在取得不论什么请求參数前运行request.setCharacterEncoding("UTF-8")方法才有作用。
2.GET请求參数编码处理
setCharacterEncoding()方法仅仅对body中字符编码才有作用。也就是基本上这种方法值对POST产生作用,当请求是GET发送时,则未定义这种方法是否会影响容器处理
编码的方式(就其原因,是由于处理URL的是HTTPserver。而非Web容器)。
在Tomcat在GET时,使用setCharacterEncoding()方法设置编码就不会有作用,取得请求參数时仍会产生乱码。
原因是post请求和get请求存放參数位置是不同的:
post方式參数存放在请求数据包的消息体中。get方式參数存放在请求数据包的请求行的URI字段中,以?開始以param=value¶me2=value2的形式附加在URI字段之后。
而request.setCharacterEncoding(charset); 仅仅对消息体中的数据起作用。对于URI字段中的參数不起作用,我们通常通过以下的代码来完毕编码转换
String paramValue = request.getParameter("paramName");
paramValue = new String(paramValue.trim().getBytes("ISO-8859-1"), charset);
对于全局请求无论GET或者POST都须要在filter过滤器中doFilter方法中设置,比方:这里并不严格
request.setCharacterEncoding("UTF-8");
if(request.getMethod().equals("GET")){
//设置GET方法參数编码为UTF-8,通过装饰类MyServletRequestWrapper来改变request对象的请求參数编码
request=new MyServletRequestWrapper(request);
}
servlet中的请求转发
servlet中的请求转发主要有三种方式:
1、 forward:是指转发,将当前request和response对象保存,交给指定的url处理。并没有表示页面的跳转,所以地址栏的地址不会发生改变。
2、 redirect:是指重定向,包括两次浏览器请求,浏览器依据url请求一个新的页面,全部的业务处理都转到下一个页面,地址栏的地址会变发生改变。
3、 include:意为包括,即包括url中的内容。进一步理解为。将url中的内容包括进当前的servlet其中来,并用当前servlet的request和respose来运行
url中的内容处理业务.所以不会发生页面的跳转,地址栏地址不会发生改变。
redirect与include、forward的差别在于是不是同一个Request,redirect会有两次交互。
include与forward的差别在于输出的内容,include包括本身servlet与跳转页面内容的结果,而forward不包括本身servlet的内容。
servlet请求转发与重定向的差别:
request.setAttribute("test","hello");
request.getRequestDispacther("/test.jsp").forword(request,response);
response.sendRedirect("test.jsp");
一、显示结果:
1、当用request.getRequestDispacther("/test.jsp").forword(request,response); 请求转发后,结果页面输出:hello
2、当用response.sendRedirect("test.jsp");重定向后。结果页面输出:null
二、底层分析:
1、请求转发(RequestDispatcher)的过程:
客户首先发送一个请求到server端,server端发现匹配的servlet。并指定它去运行,当这个servlet运行完之后。它要调用getRequestDispacther()方法,
把请求转发给指定的test.jsp,整个流程都是在server端完毕的,并且是在同一个请求里面完毕的,因此servlet和jsp共享的是同一个request,在servlet里面放的全部东西,在jsp中都能取出来,因此,jsp能把结果getAttribute()出来,getAttribute()出来后运行完把结果返回给client。
整个过程是一个请求,一个响应。
2、重定向(sendRedirect)的工作原理:
客户发送一个请求到server。server匹配servlet。这都和请求转发一样,servlet处理完之后调用了sendRedirect()这种方法,这种方法是response的方法,所以。当这个servlet处理完之后,看到response.senRedirect()方法,马上向client返回这个响应。响应行告诉client你必需要再发送一个请求。去訪问test.jsp。
紧接着client受到这个请求后,立马发出一个新的请求,去请求test.jsp,这里两个请求互不干扰,相互独立,在前面request里面setAttribute()的不论什么东西,在后面的request里面都获得不了。
可见,在sendRedirect()里面是两个请求,两个响应。
这种方法会在响应中设置HTTP状态码301以及Location标头,浏览器接受到这个标头,会又一次使用GET方法请求指定的URL,因此地址栏上会反线URL的变更。
三、表面分析:
1、当用RequestDispatcher请求转发后,地址栏为http://localhost:8080/test/TestServlet
这真好应正了上面的分析,我们起初请求的就一个servlet,至于你server端怎么转,流程怎么样的,我client根本就不知道,我发了请求后我就等
着响应,那你server那边愿意怎么转就怎么转。我client不关心也没法知道,所以当server端转发到jsp后,它把结果返回给client,client根本就
不知道你这个结果是我真正訪问的servlet产生的,还是由servlet转发后下一个组件产生的。
2、当用sendRedirect重定向后,地址栏为http://localhost:8080/test/test.jsp
由于这个时候,client已经知道了他第二次请求的是test.jsp,server已经告诉client要去訪问test.jsp了。所以地址栏里会显示想要訪问的结果。
假设在处理请求的过程中发现一些错误。而你想要传送server默认的状态与错误信息。能够使用sendError()方法。
因为利用到HTTP状态码,要求浏览器重定向网页,因此。sendError()方法相同必须在未确认输出前运行,否则会抛出IllegalStateException
response.sendError(404);
package com.zghw.servlet.demo; import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Date;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Map; import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession; /**
* Servlet implementation class MyRequestServlet
*/
@WebServlet("/myRequestServlet/*")
public class MyRequestServlet extends HttpServlet {
static void f(Object obj) {
System.out.println(obj);
}
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// http://localhost:8080/servlet-demo/myRequestServlet/test? id=123&abc=222&abc=333
// URL信息
Request_URL(request);
// request请求行
RequestLine(request);
// request请求header
RequestHeader(request);
// client和server端信息地址
RequestLocalRemoteAddr(request);
// 会话cookie和session
RequestCookieSession(request);
// request请求參数及属性
RequestParameter(request);
// 请求转发
RequestDispatcher(request, response);
} /**
* 请求转发
*/
private void RequestDispatcher(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
f("============ RequestDispatcher ==================");
// 转发的类型FORWARD,INCLUDE,REQUEST,ASYNC,ERROR
// REQUEST代表来自client的请求
// INCLUDE代表了当前(servlet、jsp、html)是被包括在其它(servlet、jsp、html)里的
// FORWARD代表了由其它Servlet、jsp或html转发过来的
// ASYNC
// ERROR
DispatcherType dispathcerType = request.getDispatcherType();
f(dispathcerType);
// 能够使用?id=111能够使用像get方法一样传送字符串查询參数
RequestDispatcher dispatcher = request
.getRequestDispatcher("/ms1? id=111"); // 在include()或forward()时包括请求參数的作法,仅适用于传递字符串给还有一个Servlet。在调派请求的过程中,假设由必须共享的“对象”
// 能够设置给请求对象成为属性,称为请求范围属性。
// 在使用了include或forward后,包括或转发Servlet则能够从request.getAttribute中取出这个值
// 而response.sendRedirect不能取出值。由于它是二次訪问
request.setAttribute("nowDate", new Date()); // include意为包括,即包括url中的内容,进一步理解为。将url中的内容包括进当前的servlet其中来,并用当前servlet的request和
// respose来运行url中的内容处理业务.所以不会发生页面的跳转。地址栏地址不会发生改变。
// 使用include()时。被包括的Servlet中不论什么对请求标头的设置都会被忽略。。被包括的Servlet中能够使用getSession()方法取得HttpSession对象
// dispatcher.include(request, response); // forward是指转发,将当前request和response对象保存,交给指定的url处理。并没有表示页面的跳转,所以地址栏的地址不会发生改变。 dispatcher.forward(request, response); // response.sendRedirect是指重定向,包括两次浏览器请求,浏览器依据url请求一个新的页面。全部的业务处理都转到下一个页面,
// 地址栏的地址会变发生改变。
// response.sendRedirect(request.getContextPath()+"/ms"); // 假设在处理请求的过程中发现一些错误,而你想要传送server默认的状态与错误信息,能够使用sendError()方法。
// 由于利用到HTTP状态码,要求浏览器重定向网页,因此,sendError()方法相同必须在未确认输出前运行。否则会抛出IllegalStateException
// 能够使用HttpServletResponse来查询状态码
// response.sendError(HttpServletResponse.SC_NOT_FOUND);
// 当然能够自己定义原因短语
// response.sendError(HttpServletResponse.SC_NOT_FOUND, "找不到页面");
f("分发后还运行我");
f("============ RequestDispatcher end ==================");
} /**
* 获取请求參数
*
* @param request
* @throws UnsupportedEncodingException
*/
private void RequestParameter(HttpServletRequest request)
throws UnsupportedEncodingException {
f("============request parameter==================");
// 得到编码方式,这个body内容的编码方式,及POST方式提交的编码方式。
String characterEncoding = request.getCharacterEncoding();
f(characterEncoding);
// 得到全部參数值
Enumeration<String> paramterNames = request.getParameterNames();
while (paramterNames.hasMoreElements()) {
String name = paramterNames.nextElement();
// 依据參数名称得到參数值
f(name + "=" + request.getParameter(name));
}
// 得到全部參数值,以map的形式存储,
Map<String, String[]> parameterMap = (Map<String, String[]>) request
.getParameterMap();
for (Map.Entry<String, String[]> entry : parameterMap.entrySet()) {
System.out.print(entry.getKey() + "=");
if (entry.getValue() != null && entry.getValue().length > 0) {
for (String value : entry.getValue()) {
System.out.print(value + ",");
}
}
}
f("");
// 得到參数的多个值,比方多选框
String[] parameterValues = request.getParameterValues("abc");
if (parameterValues != null) {
for (String pv : parameterValues) {
// 没实用
// String p = URLDecoder.decode(pv, "UTF-8");
// 直接设置编码方式
// String p = new String(pv.getBytes("ISO-8859-1"),"UTF-8");
System.out.print(pv + ",");
}
}
// 依据參数名称得到參数值
String parameter = request.getParameter("id");
f("");
f(parameter);
f("============request parameter end==================");
} /**
* 会话功能 cookie 和session
*
* @param request
*/
private void RequestCookieSession(HttpServletRequest request) {
f("============cookies session ==================");
// 取得全部Cookie
Cookie[] cookies = request.getCookies();
// 取得session
HttpSession hs = request.getSession();
// 假设当前session为空则创建一个,true为自己主动创建session
HttpSession httpSession = request.getSession(true);
// 当前的请求的sessionID。没有指定则返回null
String sessionId = request.getRequestedSessionId();
f("改变前的sessionId=" + sessionId);
// request.changeSessionId();
// sessionId = request.getRequestedSessionId();
f("改变后的sessionId=" + sessionId);
boolean sessionIdFromCookie = request.isRequestedSessionIdFromCookie();
f("sessionID是从Cookie中来的?" + sessionIdFromCookie);
boolean sessionIdFromURL = request.isRequestedSessionIdFromURL();
f("sessionId是从URL来的?" + sessionIdFromURL);
boolean sessionIdValid = request.isRequestedSessionIdValid();
f("sessionId是有效的?" + sessionIdValid);
f("============cookies session end==================");
} /**
* client地址信息和server端地址信息
*
* @param request
*/
private void RequestLocalRemoteAddr(HttpServletRequest request) {
f("============IP Local port==================");
// server的IP地址
String localAddr = request.getLocalAddr();
f(localAddr);
// serverIP地址相应的域名
String localName = request.getLocalName();
f(localName);
// 本地使用的端口号
int port = request.getLocalPort();
f(port);
// 假设client提供了Accept-Language 值,则使用client提供的语言,否则默认就是用server设置的国际化语言
Locale locale = request.getLocale();
f(locale);
// 和上面的不同之处在于这个是多个server语言。默认是使用server设置的本地语言
Enumeration<Locale> enumLocale = request.getLocales();
while (enumLocale.hasMoreElements()) {
Locale loc = enumLocale.nextElement();
f(loc);
}
// clientIP地址
String remoteAddr = request.getRemoteAddr();
f(remoteAddr);
// 获得client的主机名,假设没有就获取IP地址
String remoteHost = request.getRemoteHost();
f(remoteHost);
// client端口号
int remotePort = request.getRemotePort();
f(remotePort);
// client登录用户信息
String user = request.getRemoteUser();
f(remotePort);
f("============IP Local port end ==================");
} /**
*
* @param request
*/
private void RequestHeader(HttpServletRequest request) {
// 得到请求中全部header的名称集合
Enumeration<String> en = request.getHeaderNames();
f("============Header==================");
while (en.hasMoreElements()) {
// 得到header名称
String name = en.nextElement();
// 取得header相应的值
f(name + "=" + request.getHeader(name));
}
// 查询header中的时间戳,比方If-Modified-Since,,假设不存在返回-1
long modified = request.getDateHeader("If-Modified-Since");
f(modified);
// 查询head中相应的App值
Enumeration<String> getHeaders = request.getHeaders("App");
while (getHeaders.hasMoreElements()) {
// 得到header名称
String name = getHeaders.nextElement();
// 取得header相应的值
f(name + "=" + request.getHeader(name));
}
// 查询Header头返回一个数值,假设不存在返回-1
int intValue = request.getIntHeader("abc");
f(intValue);
f("============Header end==================");
} /**
* reqeust请求行
* 请求报文请求server对资源进行一些操作。请求报文的起始行,或称为请求行,包括了一个方法和一个请求URL。这种方法描写叙述了server应该运行的操作,
* 请求URL描写叙述了要对那个资源运行这种方法。请求行中还包括HTTP的版本号,用来告知server。client使用的是哪种HTTP。
*/
private void RequestLine(HttpServletRequest request) {
f("============request line==================");
// 请求使用的协议及版本号
String protocol = request.getProtocol();
f(protocol);
// 请求使用的方法比方GET POST
String method = request.getMethod();
f(method);
f("============request line end==================");
} /**
* 请求取得URL的全部信息
*
* @param request
* @throws UnsupportedEncodingException
*/
private void Request_URL(HttpServletRequest request)
throws UnsupportedEncodingException {
f("============request URL ==================");
// 实例http://localhost:8080/servlet-demo/myRequestServlet/test?id=123&abc=222
// 方案实际上是规定怎样訪问制定资源的主要标识符。它会告诉负责解析URL的应用程序应该使用什么协议。 // 方案组件必须以一个字母符号開始,有第一个“:”符号将其与URL的其余部分分隔开来。方案名是大写和小写无关的。
String scheme = request.getScheme();
// 输出:http
f(scheme);
// 主机组件表示了因特网上能够訪问资源的宿主机器
String serverName = request.getServerName();
// 输出:localhost
f(serverName);
// 端口组件标识了server正在监听的网络端口。
int serverPort = request.getServerPort();
// 输出:8080
f(serverPort);
// 项目在web容器中的根路径,环境路径。 假设应用程序环境路径和Webserver环境根路径相同。则应用程序环境路径为空字符串,
// 假设不是。则应用程序环境路径以“/”开头。不包括“/”结尾。
String contextPath = request.getContextPath();
// 输出:/servlet-demo
f(contextPath);
// 资源位于server的什么地方。路径通常非常像一个分级的文件系统路径。 // Servlet中资源路径
String servletPath = request.getServletPath();
// 输出:/myRequestServlet/test
f(servletPath);
// 通过提问题或者查询来缩小所请求资源类型的范围。 // 查询字符串以一系列“名/值”对的形式出现,名值对之间用字符“&”分隔
String queryString = request.getQueryString();
// 输出:id=123&abc=222
f(queryString);
f(URLDecoder.decode(queryString, "UTF-8"));
// 路径信息不包括请求參数,值的是不包括环境路径与Servlet路径部分的额外路径信息。 // 假设没有额外路径信息。则为null(扩展映射、预设Servlet、全然匹配的情况下,getPathInfo()就会取得null)
// 假设有额外路径信息。则是一个以“/”开头的字符串。 String pathInfo = request.getPathInfo();
f(pathInfo);
// 请求的URI不包括方案主机名端口查询參数。仅包括地址
String requestURI = request.getRequestURI();
// 输出:/servlet-demo/myRequestServlet/test
f(requestURI);
// 请求的URL不包括查询參数
String requestURL = request.getRequestURL().toString();
// 输出:http://localhost:8080/servlet-demo/myRequestServlet/test
f(requestURL);
// server端真实绝对路径资源位置
String pathTranslated = request.getPathTranslated();
f(pathTranslated);
f("============request URL end==================");
} protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} }
package com.zghw.servlet.demo; import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper; /**
* 包装request的请求參数编码的转换
*
* @author zghw
*
*/
public class MyServletRequestWrapper extends HttpServletRequestWrapper {
private static final String CHARSET = "UTF-8"; public MyServletRequestWrapper(HttpServletRequest request) {
super(request);
} /**
* 重写get方法编码參数
*/
@Override
public String getParameter(String name) {
String paramter = super.getParameter(name);
paramter = ("").equals(paramter) ? null : convert(paramter);
return paramter;
} @Override
public Map<String, String[]> getParameterMap() {
Map<String, String[]> map = super.getParameterMap();
Map<String,String[]> wapper=new HashMap<String,String[]>();
if (map != null) {
for (Map.Entry<String, String[]> m : map.entrySet()) {
String[] orgin = m.getValue();
String[] values = convertArray(orgin);
wapper.put(m.getKey(), values);
}
}
return wapper;
} @Override
public String[] getParameterValues(String name) {
String[] strs = super.getParameterValues(name);
if (strs != null) {
for (int i = 0; i < strs.length; i++) {
strs[i] = convert(strs[i]);
}
}
return strs;
} private String[] convertArray(String[] orgin) {
String[] value = null;
if (orgin != null) {
value = new String[orgin.length];
int i = 0;
for (String val : orgin) {
value[i] = convert(val);
i++;
}
}
return value;
} private String convert(String paramter) {
if (paramter != null) {
try {
//设置请求參数的默认编码方式ISO-8859-1变为UTF-8
return new String(paramter.getBytes("ISO-8859-1"), CHARSET);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return null;
} }
package com.zghw.servlet.demo; import java.io.IOException;
import java.util.Date;
import java.util.Enumeration; import javax.servlet.DispatcherType;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class MyServlet1 extends HttpServlet {
private static final long serialVersionUID = 1L;
public static void f(Object obj){
System.out.println(obj);
}
public void init() throws ServletException {
System.out.println("运行Servlet1 init()");
}
public void destroy() {
System.out.println("运行Servlet1 destroy()");
}
public void doGet(HttpServletRequest request, HttpServletResponse respose)
throws ServletException, IOException {
System.out.println("运行Servlet1 service");
DispatcherType dispathcerType = request.getDispatcherType();
System.out.println("dispathcerType:"+dispathcerType);
//取出上一个转发的全部request的属性名
Enumeration<String> names = request.getAttributeNames();
while(names.hasMoreElements()){
String name = names.nextElement();
//取出属性值
f(name+":"+request.getAttribute(name));
}
String id = request.getParameter("id");
f("paramter:id="+id);
Date now=(Date)request.getAttribute("nowDate");
f("得到上一个转发送来的值:nowDate = "+now);
//FORWARD上一个servlet或JSP html的信息參数属性,对于FORWARD前一个请求须要做的事情。
if(dispathcerType.equals(DispatcherType.FORWARD)){
String contextPath=(String)request.getAttribute(RequestDispatcher.FORWARD_CONTEXT_PATH);
f("FORWARD:"+contextPath);
String pathInfo= (String)request.getAttribute(RequestDispatcher.FORWARD_PATH_INFO);
f("FORWARD:"+pathInfo);
String queryString= (String)request.getAttribute(RequestDispatcher.FORWARD_QUERY_STRING);
f("FORWARD:"+queryString);
String requestURI= (String)request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
f("FORWARD:"+requestURI);
String servletPath= (String)request.getAttribute(RequestDispatcher.FORWARD_SERVLET_PATH);
f("FORWARD:"+servletPath);
}
//INCLUDE包括类型时。能够从參数中取得的类型
if(dispathcerType.equals(DispatcherType.INCLUDE)){
String contextPath= (String)request.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH);
f("INCLUDE:"+contextPath);
String pathInfo= (String)request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO);
f("INCLUDE:"+pathInfo);
String queryString= (String)request.getAttribute(RequestDispatcher.INCLUDE_QUERY_STRING);
f("INCLUDE:"+queryString);
String requestURI= (String)request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI);
f("INCLUDE:"+requestURI);
String servletPath= (String)request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH);
f("INCLUDE:"+servletPath);
}
//ERROR类型时,能够从request.getAttribute();中取得须要的參数值
if(dispathcerType.equals(DispatcherType.ERROR)){
String errorException= (String)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
String exceptionType= (String)request.getAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE);
String errorMessage= (String)request.getAttribute(RequestDispatcher.ERROR_MESSAGE);
String requestURI= (String)request.getAttribute(RequestDispatcher.ERROR_REQUEST_URI);
String servletName= (String)request.getAttribute(RequestDispatcher.ERROR_SERVLET_NAME);
String statusCode= (String)request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
}
}
}
package com.zghw.servlet.demo; import java.io.IOException;
import java.util.Enumeration; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; public class MyFilter implements Filter { // 取得过滤器配置參数供doFilter使用
private FilterConfig filterConfig; /**
* FilterConfig包括了Filter配置的參数。能够得到ServletContext对象
*/
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("运行MyFilter init");
this.filterConfig = filterConfig;
// 获取过滤器的配置參数
Enumeration<String> paramNames = filterConfig.getInitParameterNames();
while (paramNames.hasMoreElements()) {
String name = paramNames.nextElement();
System.out.println("过滤器配置的參数 name = " + name + " , value = "
+ filterConfig.getInitParameter(name));
} // 用来測试ServletContextAttributeListenter实现类作用。
ServletContext servletContext = filterConfig.getServletContext();
// 当加入属性值时,会通知监听器调用attributeAdded
servletContext.setAttribute("test1",
"test ServletContextAttributeListenter add in MyFilter ");
// 当改变属性值时,会通知监听器调用attributeReplaced
servletContext.setAttribute("test1",
"test ServletContextAttributeListenter replace in MyFilter ");
// 当改变属性值时,会通知监听器调用attributeRemoved
servletContext.removeAttribute("test1");
} /**
* 当请求来到容器,而容器发现调用Servlet的serivce方法前,能够应用某过滤器时。就会调用该过滤器的doFilter()方法,
* 能够在doFilter()方法中进行service()方法的前置处理,而后决定是否调用FilterChain的doFilter()方法。 * 假设调用了FilterChain的doFilter
* ()方法,就会运行下一个过滤器,假设没有下一个过滤器了,就调用请求目标Servlet的service()方法。
* 假设由于某个情况(如用户没有通过验证
* )而没有调用FilterChain的doFilter()方法。则请求就不会继续交给接下来的过滤器或目标Servlet,
* 这时候就是所谓的拦截请求(从Servlet的观点来看。根本不知道浏览器有发出请求)。
* 在陆续调用完FIlter实例的doFilter()仍至Servlet的service
* ()之后,流程会以堆栈顺序返回,所以在FilterChain的doFilter()运行完成后。 就能够针对service()方法做兴许处理。
*
* 仅仅须要知道FilterChain运行后会以堆栈顺序返回就可以。 在实现Filter接口时,不用理会这个Filter前后是否有其它Filter,
* 应该将之作为一个独立的元件设计。 Servlet/JSP提供的过滤器机制,事实上是Java EE设计模式中Interceptor
* Filter模式的实现。假设希望能够弹性地抽换某功能地前置与后置处理元件 (比如Servlet/JSP
* 中Servlet的service()方法的前置与后置处理)。就能够应用Interceptor Filter模式。
*/
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
// POST方法參数编码为UTF-8
request.setCharacterEncoding("UTF-8");
if (request.getMethod().equals("GET")) {
// 设置GET方法參数编码为UTF-8,通过装饰类MyServletRequestWrapper来改变request对象的请求參数编码
request = new MyServletRequestWrapper(request);
}
System.out.println("运行MyFilter doFilter");
System.out.println("运行MyFilter doFilter before");
chain.doFilter(request, response);
response.setCharacterEncoding("UTF-8");
System.out.println("运行MyFilter doFilter after");
} @Override
public void destroy() {
System.out.println("运行MyFilter destroy");
} }
Request介绍及演示样例 PART1的更多相关文章
- ArcSDE SDK For Java二次开发介绍、演示样例
在一个工作中,遇到了须要java后台来查询ArcGIS 中用到的Oracle数据库空间数据,因为对ArcGIS空间数据首次接触,仅仅知道Oracle能够使用ST_GEOMETRY字段存储,例如以下图 ...
- 【Unity 3D 游戏开发】Unity3D 入门 - 工作区域介绍 与 入门演示样例
一. 工作区域具体解释 1. Scence视图 (场景设计面板) scence视图简单介绍 : 展示创建的游戏对象, 能够对全部的游戏对象进行 移动, 操作 和 放置; -- 演示样例 : 创建一个球 ...
- 展示C代码覆盖率的gcovr工具简单介绍及相关命令使用演示样例
(本人正在參加2015博客之星评选,诚邀你来投票,谢谢:username=zhouzxi">http://vote.blog.csdn.net/blogstar2015/candida ...
- HBase总结(十一)hbase Java API 介绍及使用演示样例
几个相关类与HBase数据模型之间的相应关系 java类 HBase数据模型 HBaseAdmin 数据库(DataBase) HBaseConfiguration HTable 表(Table) H ...
- 让你提前认识软件开发(19):C语言中的协议及单元測试演示样例
第1部分 又一次认识C语言 C语言中的协议及单元測试演示样例 [文章摘要] 在实际的软件开发项目中.常常要实现多个模块之间的通信.这就须要大家约定好相互之间的通信协议,各自依照协议来收发和解析消息. ...
- Eureka 的 Application Client client的执行演示样例
上篇以一个 demo 演示样例介绍了 Eureka 的 Application Service 客户端角色.今天我们继续了解 Eureka 的 Application Client 客 ...
- Cocos2d-x 3.2 Lua演示样例 XMLHttpRequestTest(Http网络请求)
Cocos2d-x 3.2 Lua演示样例 XMLHttpRequestTest(Http网络请求) 本篇博客介绍Cocos2d-x 3.2Lua演示样例中的XMLHttpRequestTes ...
- 通过Canvas及File API缩放并上传图片完整演示样例
创建一个只管的用户界面,并同意你控制图片的大小.上传到server端的数据,并不须要处理enctype为 multi-part/form-data 的情况.只一个简单的POST表单处理程序就能够了. ...
- Eureka 的 Application Service client的注冊以及执行演示样例
Eureka 服务器架起来了(关于架设步骤參考博客<Linux 下 Eureka 服务器的部署>),如今怎样把我们要负载均衡的服务器(也就是从 Application Cl ...
随机推荐
- 如何使用 DBCC MEMORYSTATUS 命令来监视 SQL Server 2005 中的内存使用情况
https://technet.microsoft.com/en-us/solutionaccelerators/dd537566.aspx 注意:这篇文章是由无人工介入的微软自动的机器翻译软件翻译完 ...
- andriod 启动日历
Intent intent=new Intent();intent.setComponent(new ComponentName("com.android.calendar", & ...
- ylbtech-LanguageSamples-Indexers_2(索引器)
ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-Indexers_2(索引器) 1.A,示例(Sample) 返回顶部 Indexers ...
- iOS:quartz2D绘图
Quartz-2D:绘图 一.介绍: •Quartz 2D是一个二维图形绘制引擎,支持iOS环境和Mac OS X环境 •Quartz 2D API可以实现许多功能,如基于路径的绘图.透明度.阴影 ...
- 用google mock模拟C++对象
google mock是用来配合google test对C++项目做单元测试的.它依赖于googletest(参见我上篇文章<如何用googletest写单元测试>: http://blo ...
- vue项目配置使用flow类型检查
你是否经常在debug那些简单可避免的bug?可能你给函数传参的时候搞错了参数的顺序,或者本来应该传个Number类型的参数,你传了一个String类型?JavaScript的弱类型是这一类bug的罪 ...
- C#高级编程八十二天----用户自己定义异常类
用户自己定义异常类 前面已经说了不少关于异常的问题了,如今来给大家说一下自己定义异常时咋个回事以及咋样. 为啥会出现自己定义异常类呢? 用用脚趾头想想也明确,是为了定义咱们自己的异常,自己定义异常 ...
- 有关﹤![CDATA[ ]]> 说明
CDATA DTD中的属性类型 全名:character data 在标记CDATA下,所有的标记.实体引用都被忽略,而被XML处理程序一视同仁地当做字符数据看待, CDATA的形式如下: <! ...
- iOS7重磅推新--不断尝试与重新设计的过程
来源:GBin1.com iOS7重磅推新--不断尝试与重新设计的过程 或许你心里已经有了关于iPhone最新操作系统的评价,可能你喜欢它,也可能不喜欢,事实上大多数设计者不喜欢.设计界似乎一致认为I ...
- npm显示已安装的包
npm list -g --depth 0 显示安装过的npm包!