Request&Response

1 HttpServletResponse

Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。

响应正文(主体)

getWrite(); 字符输出流

getOutputStream(); 字节输出流

Request&Response_第1张图片
image.png

响应编码

案例:向客户端输出中文


@Override

**protected** **void**doGet(HttpServletRequest req, HttpServletResponse resp)

**throws** ServletException, IOException {

// 设置响应类型和字符编码为UTF-8, 这样支持汉字显示

//  resp.setContentType("text/html");

//  resp.setCharacterEncoding("UTF-8");

//设置客户编码类型

resp.setHeader("Content-Type", "text/html;charset=utf-8");

//不设置编译类型,默认编码发送数据 ISO-8859-1(没有中国二字编码),此时会发生乱码

resp.getWriter().write("hello你好");

}
Request&Response_第2张图片
image.png

响应状态码

常见的状态码参照:http://tool.oschina.net/commons?type=5

404 请求失败,请求所希望得到的资源未被在服务器上发现

200 请求已成功,请求所希望的响应头或数据体将随此响应返回。

302 重定向

500 服务抛出异常

  • 掌握如何设置状态响应码
Request&Response_第3张图片
image.png

文件下载

@Override

**protected** **void**doGet(HttpServletRequest req, HttpServletResponse resp)

**throws** ServletException, IOException {

String filename= "Java基础考试题卷.docx";

//下载文件

String path= "C:/Users/guoyongfeng/Desktop/upload/"+ filename;

FileInputStream fis= **new** FileInputStream(path);

//设置请求头,文件名需要UTF-8编码

filename = URLEncoder.*encode*(filename, "UTF-8");

resp.setHeader("Content-disposition", "attachment;filename="+ filename);

**byte**[] bs= **new** **byte**[1024];

ServletOutputStream sos= resp.getOutputStream();

**int** len = 0;

**while**((len= fis.read(bs)) != -1){

sos.write(bs, 0, len);

}

fis.close();

}

手写验证码

  • 输出随机图片(CAPTCHA图像):Completely Automated Public Turing Test to Tell Computers and Humans Apart (全自动区分计算机和人类的测试)

  • 相关主要类(JDK 查看API)

BufferedImage:内存图像

Graphics:画笔

ImageIO:输出图像

Servlet


@Override

**protected** **void**doGet(HttpServletRequest req, HttpServletResponse resp)

**throws** ServletException, IOException {

//创建内存对象

BufferedImage image= **new** BufferedImage(***WIDTH***, ***HEIGHT***, BufferedImage.***TYPE_INT_RGB***);

//图像

Graphics g= image.getGraphics();

//设置背景

g.setColor(Color.***YELLOW***);

//填充

g.fillRect(0, 0, ***WIDTH***, ***HEIGHT***);

//设置边框

g.setColor(Color.***BLUE***);

//加干扰线

**for**(**int** i=0;i<4;i++){

**int** xStart= **new** Random().nextInt(***WIDTH***);

**int** yStart= **new** Random().nextInt(***HEIGHT***);

**int** xEnd= **new** Random().nextInt(***WIDTH***);

**int** yEnd= **new** Random().nextInt(***HEIGHT***);

g.drawLine(xStart, yStart, xEnd, yEnd);

}

**int** x = 5;

//画随机数

**for**(**int** i= 0; i< 4;i++){

g.drawString(**new**Random().nextInt(9) + "", x, 20);

x+=20;

}

//输出图片 设置响应格式

resp.setContentType("image/jpeg");

ImageIO.*write*(image, "JPEG",resp.getOutputStream());

}

html

Request&Response_第4张图片
image.png
Request&Response_第5张图片
image.png

工具类实现验证码

Request&Response_第6张图片
image.png

设置客户端不需要缓存【pass】

@Override

**protected** **void**doGet(HttpServletRequest req, HttpServletResponse response)

**throws** ServletException, IOException {

//浏览器刷新时就不会有缓存

response.addHeader("Pragma", "no-cache");

response.setHeader("Cache-Control", "no-cache");

response.setHeader("Expires", "0");

ValidateCode code= **new** ValidateCode(***WIDTH***, ***HEIGHT***, 4, 6);

code.write(response.getOutputStream());

}

自动刷新功能


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

// **TODO** Auto-generated method stub

response.setContentType("text/html;charset=UTF-8");

//response.setHeader("Refresh", "1");//每隔一秒刷新一次

response.setHeader("Refresh", "5;URL=index.html");//3秒后转到另一页面

response.getWriter().write("注册成功!3秒后会自动跳转,苦没有中转点击这里");

}

请求重定向

请求重定向指:一个web资源收到客户端请求后,通知客户端去访问另外一个web资源,这称之为请求重定向。

重定向特点:地址栏会变并发送2次请求,增加服务器负担**

实现方式

response.sendRedirect()

实现原理:

302/307状态码和location头即可实现重定向

转发特点:地址栏不会变,客户端发送一次请求**

response细节

getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据

getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 会抛异常。

Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。

Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。

HttpServletRequest

简介:

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

request常用方法

获得客户端信息

  • getRequestURL方法返回客户端发出请求时的完整URL。

  • getRequestURI方法返回请求行中的资源名部分。

  • getQueryString 方法返回请求行中的参数部分。

  • getRemoteAddr方法返回发出请求的客户机的IP地址

  • getRemoteHost方法返回发出请求的客户机的完整主机名

  • getRemotePort方法返回客户机所使用的网络端口号

  • getLocalAddr方法返回WEB服务器的IP地址。

  • getLocalName方法返回WEB服务器的主机名

  • getMethod得到客户机请求方式

获得客户端请求头

  • getHead(name)方法

  • getHeaders(String name)方法

  • getHeaderNames方法

Request&Response_第7张图片
image.png

获得客户端请求参数(客户端提交的数据)

  • getParameter(name)方法

  • getParameterValues(String name)方法

  • getParameterNames方法

  • getParameterMap方法 //做框架用,非常实用

  • getInputStream

Request的应用

获取表单数据一

目标:掌握通getParameter和getParameterValues获取请求参数

掌握POST和GET请求解决乱码的方案

掌握表单提交通过都用POST方法

HTML:Post请求

[
Request&Response_第8张图片
image.png

用户名:
密---码:
性---别:
爱---好:写代码 看书 听课
备---注:
| | LoginServlet:POST请求 | | **protected** **void**doPost(HttpServletRequest request, HttpServletResponse response) **throws** ServletException, IOException { // **TODO** Auto-generated method stub //设置字符编码,解决乱码问题,只对post有效 request.setCharacterEncoding("utf-8"); //接收表单请求参数 String username= request.getParameter("username"); String password= request.getParameter("password"); String gender= request.getParameter("gender"); String[] hobby= request.getParameterValues("hobby"); String remark= request.getParameter("remark"); System.***out***.println(username); System.***out***.println(password); System.***out***.println(gender); System.***out***.println(Arrays.*toString*(hobby)); System.***out***.println(remark); }
Request&Response_第9张图片
image.png

LoginServlet:GET请求

  • 在GET请求中,tomcat8不会有乱码,tomcat7会有乱码

  • 因为tomcat7的接收参数时采用了IOS-8859-1编码

  • 而tomcat8接收参数时采用了utf-8

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

//接收表单请求参数

String username= **new** String(request.getParameter("username").getBytes("ISO-8859-1"), "UTF-8");

String password= **new** String(request.getParameter("password").getBytes("ISO-8859-1"), "UTF-8");

String gender= **new** String(request.getParameter("gender").getBytes("ISO-8859-1"), "UTF-8");

String[] hobby= request.getParameterValues("hobby");//多选框,转比较麻烦

String remark= **new** String(request.getParameter("remark").getBytes("ISO-8859-1"), "UTF-8");

System.***out***.println(username);

System.***out***.println(password);

System.***out***.println(gender);

System.***out***.println(Arrays.*toString*(hobby));

System.***out***.println(remark);

}

获取表单数据二

掌握 通过getParameterMap方法,封装参数到一个模型

这代码写在doPost中

Request&Response_第10张图片
image.png
Request&Response_第11张图片
image.png
**public** **class** Lesson04Servlet **extends** HttpServlet{

@Override

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

//post请求时,中文会乱码,解决方法setCharacterEncoding,只针对post请求有效

request.setCharacterEncoding("UTF-8");

//创建用户对象

User user= **new** User();

//获取请求参数

/**

 * key  value

* username  {"gyf"};

 * password     {"123"};

 * hobby  {"studying","money"}

 */

Map map= request.getParameterMap();

**try** {

**for**(Entry entry: map.entrySet()){

String pname= entry.getKey();

/*if(pname.equals("username")){

user.setUsername(entry.getValue()[0]);

}else if(pname.equals("hobby")){

user.setHobby(entry.getValue());

}*/

//反射

//创建属性描述器

PropertyDescriptor pd= **new** PropertyDescriptor(entry.getKey(), User.**class**);

//获取写入方法对象

Method method= pd.getWriteMethod();

//通过反射调用方法【怎么获取方法的参数类型】

Class[] clzs= method.getParameterTypes();

**if**(clzs.length == 0){

**return**;

}

String clzName= clzs[0].toString();

String[] values= entry.getValue();

**if**(clzName.contains("[Ljava.lang.String")){

System.***out***.println("数组...");

method.invoke(user, (Object)values);

}**else**{

System.***out***.println("非数组...");

method.invoke(user, values[0]);

}

/*String[] values = entry.getValue(); 这种方式有bug

if(values.length == 1){

method.invoke(user, values[0]);

}else{

method.invoke(user, (Object)values);

}

*/

}

} **catch**(Exception e) {

// **TODO** Auto-generated catch block

e.printStackTrace();

}

System.***out***.println(user);

}

}

获取表单数据三

课程目标

1.掌握通过beanutils来封装请求参数

2.了解什么是Bean

JavaBean 是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。JavaBean 通过提供符合一致性设计模式的公共方法将内部域暴露成员属性,set和get方法获取

首先需要导入下面两个包

image.png
Request&Response_第12张图片
image.png

获取原始表单数据

通过InputStream来获取最原始的表单数据

Request&Response_第13张图片
image.png

实现请求转发

  • 请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。

  • request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。

  • request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。

setAttribute方法

getAttribute方法

removeAttribute方法

getAttributeNames方法

Request&Response_第14张图片
image.png

实现请求重定向

重定向机制的运作流程

1、用户在浏览器端输入特定URL,请求访问服务器端的某个组件

2、服务器端的组件返回一个状态码为302的响应结果。

3、当浏览器端接收到这种响应结果后,再立即自动请求访问另一个web组件

4、浏览器端接收到来自另一个web组件的响应结果。

HttpServeltResponse的sendRedirect(String location)用于重定向

|

[图片上传失败...(image-2c5c66-1556024237124)]

|

转发和重定向的区别

域对象:session,request,page。。。

域:区间、范围

  • 重定向:以前的request中存放的变量全部失效,并进入一个新的request作用域。

  • 转发:以前的request中存放的变量不会失效,就像把两个页面拼到了一起。

转发存放在Request中的变量不会失效

Request&Response_第15张图片
image.png

include()、forward()、sendRedirect()的区别【面试题】

假定第一次请求的为servlet1,处理转发的为servlet2
include()方法将请求转发给servlet2,servle2对该请求做出了的响应并入到原来的servlet1响应对象中,原来的servlet1还可以继续输出响应信息。
forward方法将请求转发给其他的servlet2,servlet2负责对请求做出响应,而原先的servlet1的执行则终止。
Request&Response_第16张图片
image.png
sendRedict()则是在浏览器请求servlet1之后,重新告诉浏览器将请求重新定位到servlet。

你可能感兴趣的:(Request&Response)