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. centos6.5 网卡服务开机自动启动

    今天打开许久没用的centos之后,发现网络服务器不可用,通过service network restart 依然无法使用,简单记录一下处理过程: 1.通过setup 命令查看Network conf ...

  2. 【转载】无需图片,使用CSS3实现圆角按钮

    原文地址:http://www.open-open.com/home/space-37924-do-blog-id-5789.html 首先来看看效果: 事例HTML代码: <a href=&q ...

  3. PHP源码加密- php-beast

    php-beast 详细介绍 使用案例: http://www.beastcoder.com/ PHP Beast是一个源码加密模块,使用这个模块可以把PHP源码加密并在此模块下运行. 为什么要用PH ...

  4. 洛谷 P1739 表达式括号匹配【STL/stack/模拟】

    题目描述 假设一个表达式有英文字母(小写).运算符(+,-,*,/)和左右小(圆)括号构成,以"@"作为表达式的结束符.请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返 ...

  5. Group Shifted Strings -- LeetCode

    Given a string, we can "shift" each of its letter to its successive letter, for example: & ...

  6. [LOJ6280]数列分块入门 4

    题目大意: 给你一个长度为$n(n\leq50000)$的序列$A$,支持进行以下两种操作:​ 1.将区间$[l,r]$中所有数加上$c$: 2.询问区间$[l,r]$在模$c+1$意义下的和.思路: ...

  7. jsp笔记2(编译指令与动作指令)

    一.jsp的编译指令是通知jsp引擎的消息,不会生成输出. jsp的3个编译指令: page:针对当前页面的指令   include:包含另一个页面的指令   taglib:用于定义和访问自定义标签 ...

  8. iOS中的MD5(base64)加密

    MD5(base64)是一种结合MD5摘要和base64编码的密文处理方式,加密后的结果为24位字符串,且后两位为==,例如:1的加密结果为xMpCOKC5I4INzFCab3WEmw==. 下面是加 ...

  9. Ubuntu16.04 -- 后台进程Nohup

    nohup用于使程序在用户退出登陆.关闭终端之后仍能继续运行 用法: nohup your_command & #(符号&使程序在后台运行) exit #(退出nohup模式) 启动后 ...

  10. 常用VBA小技巧

    用对话框选取文件路径(单个文件) 删除导入csv等文本文件后留下的 Data connections 增加新的工作表并并命名 Worksheets.Add(After:=Worksheets(Work ...