1 HttpServletResponse
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
响应正文(主体)
getWrite(); 字符输出流
getOutputStream(); 字节输出流
响应编码
案例:向客户端输出中文
@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你好");
}
响应状态码
常见的状态码参照:http://tool.oschina.net/commons?type=5
404 请求失败,请求所希望得到的资源未被在服务器上发现
200 请求已成功,请求所希望的响应头或数据体将随此响应返回。
302 重定向
500 服务抛出异常
- 掌握如何设置状态响应码
文件下载
@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
工具类实现验证码
设置客户端不需要缓存【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方法
获得客户端请求参数(客户端提交的数据)
getParameter(name)方法
getParameterValues(String name)方法
getParameterNames方法
getParameterMap方法 //做框架用,非常实用
getInputStream
Request的应用
获取表单数据一
目标:掌握通getParameter和getParameterValues获取请求参数
掌握POST和GET请求解决乱码的方案
掌握表单提交通过都用POST方法
HTML:Post请求
[
|
|
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);
}
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中
**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方法获取
首先需要导入下面两个包
获取原始表单数据
通过InputStream来获取最原始的表单数据
实现请求转发
请求转发指一个web资源收到客户端请求后,通知服务器去调用另外一个web资源进行处理。
request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
request对象同时也是一个域对象,开发人员通过request对象在实现转发时,把数据通过request对象带给其它web资源处理。
setAttribute方法
getAttribute方法
removeAttribute方法
getAttributeNames方法
实现请求重定向
重定向机制的运作流程
1、用户在浏览器端输入特定URL,请求访问服务器端的某个组件
2、服务器端的组件返回一个状态码为302的响应结果。
3、当浏览器端接收到这种响应结果后,再立即自动请求访问另一个web组件
4、浏览器端接收到来自另一个web组件的响应结果。
HttpServeltResponse的sendRedirect(String location)用于重定向
|
[图片上传失败...(image-2c5c66-1556024237124)]
|
转发和重定向的区别
域对象:session,request,page。。。
域:区间、范围
重定向:以前的request中存放的变量全部失效,并进入一个新的request作用域。
转发:以前的request中存放的变量不会失效,就像把两个页面拼到了一起。