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. java基础练习 17

    import java.util.Scanner; public class Seventheen { /*企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元 ...

  2. 将log4j2的配置文件log4j2.xml拆分成多个xml文件

    在日常的项目开发中,我们可能会使用log4j2分离系统日志与业务日志 ,这样一来,log4j2.xml 这个配置文件可能就会变得非常臃肿.庞大,那么我们可以将这个文件拆分成多个配置文件吗? 答案是肯定 ...

  3. os.path.isfile的错误

    今天写了一个程序,读取子目录(source)下的所有文件,然后转换. 程序一部分代码如下: def DtoTab(dsrc, dtarget): try: for item in os.listdir ...

  4. android launchmode singleinstance问题

    问题描述 最近测试关于launchmode的四种方式 默认模式 top singletask 都已经了解了 唯独这个instance模式 我的问题是 我们只作2个activity的假设A和B,其中A为 ...

  5. 拓扑排序【p1137】 旅行计划

    Description 小明要去一个国家旅游.这个国家有\(N\)个城市,编号为\(1\)至\(N\),并且有\(M\)条道路连接着,小明准备从其中一个城市出发,并只往东走到城市\(i\)停止. 所以 ...

  6. INFORMATION_SCHEMA获取数据库的信息

    简介 information_schema这张数据表保存了MySQL服务器所有数据库的信息.如数据库名,数据库的表,表栏的数据类型与访问权限等.再简单点,这台mysql服务器上,到底有哪些数据库.各个 ...

  7. Maven创建多模块项目(包括依赖版本号的统一更新)

    0.多项目工程的文件夹及依赖关系 bus-core-api为公共项目,app-web-ui依赖bus-core-api,app-desktop-ui依赖bus-core-api 1.创建一个父Mave ...

  8. 【视频】 Linux高级程序设计01.2开发平台及Linux环境限制

    [课程笔记] Linux环境限制 遵循规范,使用现有资源,明确系统限制,增量开发. (1)规范问题 编码的规范,让程序更易读.Linux编码规范. “见着如意”:变量,函数命名等能够让人看到名称就知道 ...

  9. 使用 SVG 来实现波浪 (wave) 动画效果

    如下图所示的波浪动画效果,实现方法有很多,比如CSS或者是js等方法都可以实现.不过,要是使用SVG来实现的,我觉得比其它两种方法都要简单.这篇文章就来讲讲使用SVG来实现类似这样的波浪动画效果是多么 ...

  10. 远程访问CENTOS的MYSQL数据库设置

    远程访问CENTOS的MYSQL数据库设置 mysql -u root grant all privileges on *.* to root@'%'identified by 'root'; 后面的 ...