web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象和代表响应的response对象。request和response对象既然代表请求和响应,那我们获取客户机提交过来的数据,只需要找request对象即可,要向客户机输出数据,只需要找response对象即可。这一节我们来看看Servlet的这两个对象:HttpServletResponse对象和HttpServletRequest对象。

1. HttpServletRequest对象

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

1)获取客户机环境信息常用的方法如下:(具体见Demo1)

getRequestURL();   //返回客户端发出请求时的完整URL
getRequestURI(); //返回请求行中的资源名部分
getQueryString(); //返回请求行中的参数部分
getRemoteAddr(); //返回发出请求的客户机的IP地址
getRemoteHost(); //返回发出请求的客户机完整主机名
getRemotePort(); //返回客户机所使用的网络端口号
getLocalAddr(); //返回WEB服务器的IP地址
getLocalName(); //返回WEB服务器的主机名
getMethod(); //得到客户机请求方式

相应的示例代码Demo1如下:

//获取客户机环境信息常见的方法
public class RequestDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { //uri标识一个资源,url标识互联网上的一个资源,所以url是uri的子集
System.out.println(request.getRequestURL());//会打印出http://localhost:8080/test/servlet/RequestDemo1
System.out.println(request.getRequestURI());//会打印出/test/servlet/RequestDemo1 //请求http://localhost:8080/test/servlet/RequestDemo1?name=eson_15
System.out.println(request.getQueryString());//打印出name=eson_15 System.out.println(request.getRemoteAddr());//打印出来访地址:127.0.0.1
System.out.println(request.getRemoteHost());//打印来访主机:127.0.0.1
System.out.println(request.getRemotePort());//打印来访端口号:3969
System.out.println(request.getLocalAddr());//打印出服务器地址:127.0.0.1 System.out.println(request.getMethod());//打印访问方式:GET/POST
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { doGet(request, response);
}
}

2)获取请求信息常用的方法--Map如下:(Demo2)

//获得客户机请求头
getHeader(String name);
getHeaders(String name); //获取指定名称的头的所有值
getHeaderNames(); //获取所有头的名称 //获得客户机请求参数(客户端提交的数据)
getParameter(name);
getParameterValues(String name); //获取指定参数名的所有值
getParameterNames(); //获取所有参数名
getParameterMap(); //获取封装数据的map集合,在框架中使用频繁

相应的示例代码Demo2如下:

public class RequestDemo2 extends HttpServlet {  

    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
<pre name="code" class="java"> //获取压缩方式 gzip,deflate.实际中在输出数据之前可以用该方法先判断浏览器是否支持gzip方式
System.out.println(request.getHeader("Accept-Encoding")); //获取指定名称的头的所有值
Enumeration e = request.getHeaders("Accept-Encoding");
while(e.hasMoreElements()) {
String value = (String) e.nextElement();
System.out.println(value);
}
System.out.println("----------------------------");
//获取所有的头和值
e = request.getHeaderNames();
while(e.hasMoreElements()) {
String name = (String) e.nextElement();
String value = request.getHeader(name);
System.out.println(name + "=" + value);
}
System.out.println("----------------------------");
//http://localhost:8080/day06/servlet/RequestDemo2?name=eson_15
System.out.println(request.getParameter("name"));//eson_15 //http://localhost:8080/day06/servlet/RequestDemo2?like=sing&like=dance
String likes[] = request.getParameterValues("like");//获取指定参数名的所有值
//重要!获取数组数据的方式(可避免空指针异常)
for(int i = 0; likes != null && i < likes.length; i++) {
System.out.println(likes[i]);//sing dance
}
System.out.println("----------------------------");
//http://localhost:8080/day06/servlet/RequestDemo2?name=eson_15&like=swim&love=you
e = request.getParameterNames();//获取所有参数名
while(e.hasMoreElements()) {
String name = (String) e.nextElement();
String value = request.getParameter(name);
System.out.println(name + "=" + value);
}
System.out.println("----------------------------");
////http://localhost:8080/day06/servlet/RequestDemo2?name=eson_15&like=swim&love=you
Map<String, String[]> map = request.getParameterMap();
for(Map.Entry<String, String[]> me : map.entrySet()) {
String name = me.getKey();
String value[] = me.getValue();
System.out.println(name + "=" + value[0]);
}
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

3)实现请求转发:(Demo3/test.jsp/Demo4)

request对象实现请求转发:请求转发指一个web资源受到客户端请求后,通知服务器去调用另一个web资源进行处理。请求转发应用场景:MVC设计模式        request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forwoard方法可以实现请求转发。        request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其他web资源处理。相关方法如下:

setAttribute();    //设置属性
getAttribute(); //获得属性值
removeAttribute(); //删除某个属性
getAttributeNames(); //获得所有属性名
//以上所有方法中的参数我都省略了,括号里为空并不代表没有参数!!

相应的示例代码如下:

//Demo3:请求转发:MVC 重点
public class RequestDemo3 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { String data = "abcd"; //开发中不能用ServletContext做容器,因为用户公用一个ServletContext,一个用户设置了数据后,另一个用户如果也设置了,将会覆盖第一个用户的值
// this.getServletContext().setAttribute("data", data); //request本身就是一个容器,我们可以用request来传递数据,不同的用户有不同的request,相互之间不会产生影响
request.setAttribute("data", data); //转发方法1,框架习惯用这种
// RequestDispatcher rd = this.getServletContext().getRequestDispatcher("/test.jsp");
// rd.forward(request, response); //转发方法2, 开发习惯用这种。这两种方法没有区别
RequestDispatcher rd = request.getRequestDispatcher("/test.jsp");
rd.forward(request, response);
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { doGet(request, response);
}
}

相应的test.jsp页面如下:

<html>
<head>
</head>
<body>
<%
//String data = (String) this.getServletContext().getAttribute("data");
String data = (String) request.getAttribute("data");
out.write(data);
%>
</body>
</html>

4)获取用户提交数据(Demo4/form.html)
        首先看一下前台页面form.html,主要是获得几个参数:

<!DOCTYPE html>
<html>
<head>
<title>form.html</title> <meta name="keywords" content="keyword1,keyword2,keyword3">
<meta name="description" content="this is my page">
<meta name="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="content-type" content="text/html;charset=UTF-8">
<!--<link rel="stylesheet" type="text/css" href="./styles.css">--> </head> <body>
<form action="/test/servlet/RequestDemo4" method="get">
用户名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
性别:
<input type="radio" name="gender" value="male"/>男
<input type="radio" name="gender" value="female"/>女<br/> 城市:
<select name="city">
<option value="beijing">北京</option>
<option value="shanghai">上海</option>
<option value="guangzhou">广州</option>
</select><br/> 爱好:
<input type="checkbox" name="like" value="sing">唱歌
<input type="checkbox" name="like" value="dance">跳舞
<input type="checkbox" name="like" value="basketball">篮球
<input type="checkbox" name="like" value="football">足球
<br/> 简历:
<textarea rows="5" cols="60" name="resume">请输入简历</textarea>
<br/> 相片:
<input type="file" name="file"/><br/> <input type="hidden" name="name" value="xxx"><br/> <input type="submit" value="提交"/> </form>
</body>
</html>

当用户提交后,自动跳转到RequestDemo4这个Servlet来处理:

public class RequestDemo4 extends HttpServlet {  

    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { request.setCharacterEncoding("UTF-8");//通过UTF-8获得浏览器中的数据 (post方式有效)
//关于GET方式,请见下面这个帖子,写的很详细,请认真阅读一下
//http://blog.csdn.net/xh16319/article/details/8456547 System.out.println(request.getParameter("username"));
System.out.println(request.getParameter("gender"));
System.out.println(request.getParameter("city")); String likes[] = request.getParameterValues("like");
for(int i = 0; likes != null && i < likes.length; i++){
System.out.println(likes[i]);
} System.out.println(request.getParameter("resume"));
System.out.println(request.getParameter("name"));
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { doGet(request, response);
} }

request比较简单,在开发中主要是用来获取前台带来的数据,以及实现跳转等等。下面看看response对象。

2. HttpServletResponse对象

这个对象是指服务器的响应,这个对象中封装了想客户端发送数据,发送响应头,发送响应状态码的方法。如:

PrintWriter getWriter();  /得到字符流
ServletOutputStream getOutputStream(); //得到字节流
void setStatus(int sc); //设置要发送的状态码
void setHead(String name, String value); //响应头 等等

response常见应用有如下几个:

1)向客户端输出中文数据:分别以OutputStream和PrintWriter输出(Demo1)

public class ResponseDemo1 extends HttpServlet {  

    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { // outputChineseByByte(response);
outputChineseByChar(response);
} private void outputChineseByChar(HttpServletResponse response)
throws IOException {
String data = "中国"; response.setHeader("content-type", "text/html;charset=UTF-8");//通知浏览器以UTF-8打开,注意里面是分号不是逗号
response.setCharacterEncoding("UTF-8");//通过response以UTF-8输出
/*
* 上面两个步骤可以用一个方法来等价
* response.setContentType("text/html;charset=UTF-8");
* 在这个方法里相当于做了以上两件事,开发中用该方法比较方便,但是不方便理解,视个人习惯而定
*/
PrintWriter out = response.getWriter();//一定要先将上面设置好才能输出
out.write(data);
} //以字节流方式输出
private void outputChineseByByte(HttpServletResponse response)
throws IOException, UnsupportedEncodingException {
//在服务器端,数据是以哪个码表输出的,那么就要控制浏览器用哪个码表打开
String data = "中国";
OutputStream out = response.getOutputStream(); response.setHeader("content-type", "text/html;charset=UTF-8");//告诉浏览器用utf-8编码打开
// 这种用html来模拟http响应头的方式也可以,即告诉浏览器以UTF-8的方式打开
// out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'>".getBytes()); out.write(data.getBytes("UTF-8"));//将“中国”这个字符通过字节输出,一定会查码表,浏览器在打开的时候若查的不是这个码表,则就会出错
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { doGet(request, response);
} }

2)文件下载和中文文件下载(Demo2)

public class ResponseDemo2 extends HttpServlet {  

    public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { // downloadFile(response); downloadErrorDemo(response);
} //中文文件的下载,中文文件名要经过URL编码
private void downloadFile(HttpServletResponse response) throws FileNotFoundException, IOException {
String realPath = this.getServletContext().getRealPath("/狗狗.jpg"); //狗狗.jpg存放在WebRoot下
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); //URLEncoding
response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName)); FileInputStream in = new FileInputStream(realPath);
int len = 0;
byte buffer[] = new byte[1024];
OutputStream out = response.getOutputStream();
while((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
} in.close();
} //文件下载注意事项:字节流可以处理任意类型的数据,字符流只能处理字符数据,如果用字符流处理字节数据会导致数据丢失
private void downloadErrorDemo(HttpServletResponse response) throws FileNotFoundException, IOException {
String realPath = this.getServletContext().getRealPath("/狗狗.jpg");
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(fileName)); FileReader in = new FileReader(realPath);
int len = 0;
char buffer[] = new char[1024];
PrintWriter out = response.getWriter();
while((len = in.read(buffer)) > 0){
out.write(buffer, 0, len);
}
/*
* 该程序下载下来的文件无法打开的原因:
* 因为任意文件都是通过二进制保存的,那么字符流在读取图片文件时,每次读取一个字符大小的二进制数,该二进制数在gb2312中可能并没有相对应的码,结果就用?代替。
* 然后写到浏览器的时候,浏览器拿到?并不能正确解析出原始的二进制数,就用0代替,这样就造成了数据的丢失。
* 所以字符流不能去读取字节数据,会导致数据的丢失
*
*/
in.close();
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { doGet(request, response);
} }

3)输出随机图片(Demo3)

public class ResponseDemo3 extends HttpServlet {  

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

        //6. 设置头,控制浏览器不要缓存图片数据
response.setHeader("cache-control", "no-cache"); //5. 通知浏览器以图片方式打开
response.setHeader("content-type","image/jpeg"); //1. 在内存中创建一幅图片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB); //2. 得到图片
Graphics2D g = (Graphics2D)image.getGraphics();
g.setColor(Color.WHITE);
g.fillRect(0, 0, 80, 20);//用白色填充整个矩形背景 //3. 向图片上写数据
g.setColor(Color.RED);//设置图片背景
g.setFont(new Font(null,Font.BOLD,20));//设置文字
g.drawString(makeNum(), 0, 20);//写上随机数 //4. 将图片写给浏览器
ImageIO.write(image, "jpg", response.getOutputStream());
} private String makeNum() {
Random r = new Random();
String num = r.nextInt(9999999) + "";//0-9999999
StringBuffer sb = new StringBuffer();
for(int i = 0; i < 7-num.length(); i++){
sb.append("0");
}
return sb.toString() + num;
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { doGet(request, response);
} }

4)发送http头以及请求重定向(这一块放在下一篇博客里解说)

3. web工程中url地址的写法

在程序中有写:

//web工程中url地址的写法
public class ResponseDemo4 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { /*只要是写地址,请统统以"/"开始,若"/"是给服务器用的则代表web工程,若"/"是给浏览器用的则代表webapps**/ //servletContext
this.getServletContext().getRealPath("/dog.jpg");//给服务器用的 //forward
this.getServletContext().getRequestDispatcher("/servlet/ResponseDemo3");//给服务器用的 //sendRedirect
response.sendRedirect("/test/servlet/ResponseDemo3");//给浏览器用的 //html <a href="/test/servlet/ResponseDemo3"></a> //给浏览器用的
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { doGet(request, response);
} }

HttpServletRequest和HttpServletResponse就介绍这么多,如有错误之处,欢迎留言指正~

Servlet的API(二)的更多相关文章

  1. Struts2(二)— Result结果配置、Servlet的API的访问、模型驱动、属性驱动

    一.Result结果配置 1.全局和局部结果 ​ 平常我们设置跳转页面,是在action标签里面加上 result标签来控制,这种设置的页面跳转,称之为局部结果页面但是我们有时候在很多个action里 ...

  2. Servlet 常用API学习(二)

    Servlet常用API学习 一.HTTP简介 WEB浏览器与WEB服务器之间的一问一答的交互过程必须遵循一定的规则,这个规则就是HTTP协议. HTTP是 hypertext transfer pr ...

  3. 七 Struts2访问Servlet的API方式二:原生方式

    Struts2访问Servlet的API方式二:原生方式 和解耦合的方式不同,原生方式既可以拿到域对象,也可以调用域对象中的方法 前端jsp: <%@ page language="j ...

  4. springmvc使用pojo和servlet原生api作为参数

    一.Pojo作为参数: 实体: package com.hy.springmvc.entities; public class User { private String username; priv ...

  5. struts2:在Action中使用Servlet的API,设置、读取各种内置对象的属性

    有两种方式可以实现在Action中使用Servlet的API.一种是使用org.apache.struts2.ServletActionContext类,另一种是使用com.opensymphony. ...

  6. Struts2学习第2天--Struts2的Servlet的API的访问 Struts2的结果页面的配置 Struts2的数据的封装(包括复杂类型)

    启动后访问jsp 输入姓名密码: 提交后跳转打action 打印: 修改类: 配置同上 结果同上. 实现这俩接口 就得到了 以上代码附上: struts.xml: <?xml version=& ...

  7. struts2学习笔记(四)——访问Servlet的API&结果跳转&数据封装

    一.Struts2访问Servlet的API 前面已经对Struts2的流程执行完成了,但是如果表单中有参数如何进行接收?又或者我们需要向页面保存一些数据,又要如何完成呢?我们可以通过学习Struts ...

  8. (转)Struts2访问Servlet的API及......

    http://blog.csdn.net/yerenyuan_pku/article/details/67315598 Struts2访问Servlet的API 前面已经对Struts2的流程已经执行 ...

  9. Servlet 常用API学习(三)

    Servlet常用API学习 (三) 一.HTTPServletRequest简介 Servlet API 中定义的 ServletRequest 接口类用于封装请求消息. HttpServletRe ...

  10. Servlet 常用API学习(一)

    Servlet常用API学习 一.Servlet体系结构(图片来自百度图片) 二.ServletConfig接口 Servlet在有些情况下可能需要访问Servlet容器或借助Servlet容器访问外 ...

随机推荐

  1. 解决:高版本jdk编译低版本代码时eclipse提示Access restriction:The type 'Unsafe' is not accessible due to restriction on required library

    在Eclipse中采用高版本jdk编译一些低版本的源码时,由于源码中使用了一些高版本中过时的API,可能就会报错,类似于: Access restriction:The type 'Unsafe' i ...

  2. [BZOJ1294][SCOI2009]围豆豆Bean 射线法+状压dp+spfa

    1294: [SCOI2009]围豆豆Bean Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 458  Solved: 305[Submit][Sta ...

  3. kuangbin系列【简单搜索】

    poj-1321棋盘问题[bfs/回溯] Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 36385   Accepted:  ...

  4. Python的程序结构[0] -> 属性/Property[0] -> 类属性、实例属性和私有属性

    类属性.实例属性和私有属性 Python中类的属性主要包括类属性,实例属性和私有属性,下面是对三种属性的简单介绍 类属性 / Class Property 类属性在__init__()之外初始化,在外 ...

  5. 线段树【p2801】教主的魔法

    Description 教主最近学会了一种神奇的魔法,能够使人长高.于是他准备演示给XMYZ信息组每个英雄看.于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1.2.--.N. 每个人的 ...

  6. Moving Average from Data Stream -- LeetCode

    Given a stream of integers and a window size, calculate the moving average of all integers in the sl ...

  7. 使用Windows Live Writer开始发布cnblogs日志的方法

    1.下载Windows Live Writer http://www.microsoft.com/zh-cn/download/confirmation.aspx?id=8621 2.安装Window ...

  8. 线程流量控制工具之Semaphore

    简介 Semaphore(信号量)是用来控制同时访问特定资源的线程数量,它通过协调各个线程,以保证合理的使用公共资源.很多年以来,我都觉得从字面上很难理解Semaphore所表达的含义,只能把它比作是 ...

  9. 阿里云ECS在CentOS 6.9中使用Nginx提示:nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)的解决方法

    说明: 1.[::]:80这个是IPv6的地址. 2.阿里云截至到今天还不支持IPv6. 解决方式: 1.普通解决方式:开启IPv6的支持,不过这个方法在阿里云行不通. vim /etc/nginx/ ...

  10. sql server 性能调优 资源等待之内存瓶颈的三种等待类型

    原文:sql server 性能调优 资源等待之内存瓶颈的三种等待类型 一.概述 这篇介绍Stolen内存相关的主要三种等待类型以及对应的waittype编号,CMEMTHREAD(0x00B9),S ...