您的位置:首页 > 理论基础 > 计算机网络

HttpServletRequest对象详解

2017-10-17 16:14 417 查看
简介:

HttpServletRequest对象代表客户端的请求,当客户端通过http访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

主要方法(实践说明):

一.获取客户机信息的常用方法

Request.java

public class Request extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();

//URL表示全部请求
String url = request.getRequestURL().toString();
System.out.println("URL = "+url);

//URI表示Web名称+资源名称
String uri = request.getRequestURI().toString();
System.out.println("URI = "+uri);

//getQuertString方法返回行中的参数部分(参数名+值)
String Quert = request.getQueryString();
System.out.println("Quert = "+Quert);
/* 虽然 = null,但该函数可以获得请求的数据,比如登录名和密码  */

//getRemoteAddr方法返回请求的客户机的IP地址
String RemoteAddr = request.getRemoteAddr();
System.out.println("RemoteAddr = "+RemoteAddr);

//getRemoteHost方法返回请求客户的完整主机名
//如果客户机没有在DNS上注册,则返回ip名,否还是IP地址
String RemoteHost = request.getRemoteHost();
System.out.println("RemoteHost = "+RemoteHost);

//getRemotePort方法返回客户机所用的网络端口号
//用户端口是根据TCP/IP协议随机给你选的一个端口,可能明天就不一样了,但服务器端口永远不变
int RemotePort = request.getRemotePort();
System.out.println("客户机使用的端口为: "+RemotePort);

//getLocalPort方法返回web服务器所使用的网络端口号
int LocalPort = request.getLocalPort();
System.out.println("服务器使用的端口为: "+LocalPort);
//getLocalAddr方法返回web服务器的IP地址
String LocalAddr = request.getLocalAddr();
System.out.println("LocalAddr= "+LocalAddr);

//getLocalName方法返回web服务器的主机名
String LocalName = request.getLocalName();
System.out.println("LocalAddr= "+LocalName);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

this.doGet(request, response);
}
}


二.获取客户机请求头

1.getHeader()方法

通过getHeather()方法可以获取到请求的任意信息头的内容。

public class GetHeaderNames extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;utf-8");
PrintWriter out = response.getWriter();

//getheader(通过消息头来获取信息)
//比如获取http的Host
String host = request.getHeader("Host");
System.out.println("Host = "+host);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

this.doGet(request, response);
}

}


2.getHeaderNames()方法

public class GetHeaderNames extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;utf-8");
PrintWriter out = response.getWriter();

//getHeaderNames方法
//获取整个Http请求的消息
//1.获取所有信息头
Enumeration<String> headers = request.getHeaderNames();
while(headers.hasMoreElements()){
//2.取出消息头的名字
String headername = headers.nextElement();
System.out.println(headername+":"+request.getHeader(headername));
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}


三.获取客户机请求参数(客户端提交的数据)

getParameter和getParameterValues用法:

直接实践:写一个表单,然后把所有上传的信息传到浏览器上:

表单文件:Infor.java

public class Infor extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.println("<form action='/Request/CLInfor' method='post'>");
out.println("用户名:<input type='text' name='username'/><br/>");
out.println("密码:<input type='password' name='pwd'/><br/>");
out.println("性别:<input type='radio' name='sex' value='男'/>男<input type='radio' name='sex' value='女'/>女<br/>");
out.println("爱好:<input type='checkbox' name='hobby' value='音乐'/>音乐<input type='checkbox' name='hobby' value='体育'/>体育<input type='checkbox' name='hobby' value='电影'/>电影<input type='checkbox' name='hobby' value='购物'/>购物<br/>");
out.println("所在城市:<select name='city'><option value='北京'>北京</option><option value='重庆'>重庆</option></select><br/>");

out.println("你的介绍:<textarea cols='20' rows='10' name='intro'>请输入介绍</textarea> <br/>");

out.println("<input type='file' name='photo'/><br/>");
//hidden:1.不希望用户看到数据 2.不希望影响界面同时给业务逻辑使用
out.println("<input type='hidden' value='abc' name='hidden'/> <br/>");

out.println("<input type='submit' value='登录'/>");
out.println("</form>");

}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

this.doGet(request, response);
}
}


处理文件 CLInfor.java

public class CLInfor extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
String u = request.getParameter("username");
String p = request.getParameter("pwd");
String sex = request.getParameter("sex");

//若过接受复选框的内容,则使用getParametersValues
String []hobbies = request.getParameterValues("hobby");

String city = request.getParameter("city");
String intro = request.getParameter("intro");
String hidden = request.getParameter("hidden");

out.println("用户名 = "+u+"<br/>");
out.println("密码 = "+p+"<br/>");
out.println("性别 = "+sex+"<br/>");
out.println("性别 = ");
if(hobbies!=null){
for(String hobby : hobbies)
out.println(hobby+" ");
}else{
out.println("你没有爱好");
}
out.println("<br/>");
out.println("所在城市 = "+city+"<br/>");
out.println("个人介绍 : "+intro+"<br/>");
out.println("隐藏控件传递的数据 : "+hidden+"<br/>");
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

this.doGet(request, response);
}
}


四.实现请求转发

请求转发指一个Web资源受到客户端请求后,通知服务器去挑用另外一个Web资源进行处理

HttpServletRequest对象(Request对象)提供了一个getRequestDispatcher方法,该方法返回了一个RequestDispatcher对象,调用这个对象的forword方法可以实现请求转发。 其中request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其他web资源处理。

直接实践:

Login.java(登录界面)

public class Login extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
request.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
out.println("<form action = '/Request/Infor' method = 'post' >");
out.println("用户名:<input type='text' name='username' /><br/>");
out.println("<input type='submit' value='登录'><br/>");
out.println("</form>");

}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

this.doGet(request, response);
}
}


Infor.java(传递页面)

public class Infor extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("utf-8");

//接受用户名
String u = request.getParameter("username");
//把u放入request域对象
request.setAttribute("username", u);
//表示使用转发的方法,把request和response对象传递给下一个页面
request.getRequestDispatcher("/Display").forward(request, response);

}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

this.doGet(request, response);
}
}


Display.java(处理界面)

public class Display extends HttpServlet {

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String username = (String) request.getAttribute("username");
out.println("接收到的用户名为:"+username);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

this.doGet
ae2b
(request, response);
}
}


运行:



呃呃。。为什么是在Display.java实现的

out.println("接收到的用户名为:"+username);


但结果url中的URI不是Display而是Infor呢?

request.getRequestDispatcher("/Display").forward(request, response);


为什么这里只需要URI资源名而不加web应用名呢?

从头开始分析吧

从浏览器放松请求到服务器再到服务器响应给浏览器整个过程如下:

1.浏览器放松http请求给web服务器

2.Web服务器解析主机:host 8080

3.Web服务器解析出web应用

4.Web服务器解析出资源名

5.Web服务器通过web.xml 查询infor的路径

6.给Infor.java创建init()方法

7.Infor 创建request,response对象,传递给doPOST

8.Infor 通过doPOST发生转向,但地域还是在web服务器中

9.Infor 给Web服务器发送通知:想要找Display资源

10.Web服务器通过web.xml查询Display资源

11.把request和response传递给Display(值得注意的是Display资源里的request对象和response对象都是Infor资源里的)

12.Display把response对象返回给Web服务器

13.web服务器把response对象中的信息拆解

14.Web服务器把结果返回给浏览器

这整个过程只发生了一次http请求,整个过程都是在web服务器中发生的。(只要没有停止,也没有回到浏览器重定向就送一次)

解释

1.不加web应用名

由于整个过程都是在Web服务器发生的,过程中并没有返回过浏览器,都是在同一个web应用中,自然就不需要添加web应用名,添加了反而是错误。

能类比的自然是response.Redirect();

response.sendRedirect("/UserLoginOne/table.html");


这是因为是重定向,web服务器响应给浏览器后,再从浏览器请求。通过抓包就可知道sendRedirect有两次而getRequestDispatcher.forward()只有一次。之所以要加web应用名,是因为从浏览器向Web服务器请求肯定是要加web应用名才能更好的定位,不然那么多web应用鬼知道是哪个。。

2.URI不是Display而是Infor

getRequestDispatcher().forward()方法使用转向的方法把request对象和response对象传递给下一个Servlet文件,所以可以这么理解:Display中的response对象是Infor资源的,web服务器解析后URI自然是Infor。

嗯,这样应该就差不多了。

sendRedirect()和forward()的区别:

1.叫法sendRedirect()为重定向,forward()为转向。

2.实际发生的位置不一样:

sendRedirect发生在浏览器

forward发生在服务器

3.用法不一样

request.gerRequestDispatcher(“/资源URI”).forward(request,response);

response.sendRedirct(“/web应用名/资源URI”);

4.能访问的URL范围不同

sendRedirect可以去外部URL

forward只能在当前web应用资源中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: