今天来回顾下之前学过Servle的Resquest以及Response的知识. 1,Request和Response技术: rr的作用: request是请求,封装用户的请求信息.若想获取请求信息,找request就行了 response是响应,封装服务器的响应信息,若想往页面写东西,找response就可以了 rr的体系结构: request 在servlet中有一个service(ServletRequest,ServletResponse) 抽象方法 在HttpServlet中实现了service(ServletRequest,ServletResponse) 并且重载了service(HttpServletRequest,HttpServletResponse) request的实现类 org.apache.catalina.connector.RequestFacade response的实现类 org.apache.catalina.connector.ResponseFacade request的体系 ServletRequest(接口) | | HttpServletRequest(接口) | | RequestFacade(类 tomcat) response的体系 ServletResponse(接口) | | HttpServletResponse(接口) | | ResponseFacade(类 tomcat) 2,Response (1)作用:响应 http响应的格式: 响应行 响应头 响应体 (2)简单介绍api 操作响应行: 响应行的格式: 协议/版本 状态码 状态码说明 HTTP/1.1 200 OK 常用的方法: setStatus(int) sendError(int) sendError(int,msg) 操作响应头: 响应头的格式: key:name key:name1,name2 --多个值的时候用逗号隔开 常用的方法: setHeader(string,string) setIntHeader(string,int) addHeader(string,string) setDateHeader(string,long) 操作响应体: 响应题就是展示的内容 getOutputStream() getWriter() (3)详解api a, 状态码: 1xx:正在请求中 2xx:完成请求响应 200:成功完成 3xx:还需浏览器进一步操作 302:还需跳转 304:浏览器去读缓存 4xx:用户请求错误 404:路径不存在 5xx:服务器错误: 500:服务器错误
常用方法: 对于非错误的状态码 setStatus(int):例如 setStatus(304) 对于的错误的状态码 sendError(int) sendError(int,msg):返回错误的信息 b,操作响应头: 响应头的格式: key:name key:name1,name2 --多个值的时候用逗号隔开 常用方法: setHeader(String key,String name):给响应设置指定的头信息 addHeader(String key,String name1):若存在则追加,反之则设置 setIntHeader(String key,int value):给响应设置指定的头信息(int类型的) addIntHeader(String key,int value):若存在则追加,反之则设置 setDateHeader(String key,Long long):给相应头设置毫秒值的 案例: 重定向: 302:还需要跳转 需要用到location 代码实现: setStatus(302); setHeader("location","跳转的路径"); 开发中时使用 sendRedirect(跳转的路径); 刷新: response.setHeader("refresh","3;url=跳转的路径"); 重定向和刷新最后的效果是一样的,同样是发送了两次请求 代码案例: 使用location跳转:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setStatus(302);
//设置跳转路径
response.setHeader("location","/dayaugmentum10/loca2");
}
使用refresh跳转:
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("refresh", "3;url=/augmentum/1.html");
}
c,操作响应体: 常用的方法: ServletOutputStream getOutputStream():字节流 PrintWriter getWriter():字符流 通过流对象.println(任意内容); 字符乱码的处理 设置响应信息的编码格式 response.setCharacterEncoding("utf-8"): 设置响应信息的编码格式并且通知浏览器用什么编码打开 response.setHeader("content-type","text/html;charset=utf-8"); 开发中使用 response.setContentType("text/html;charset=utf-8"); ☆ 在页面添加 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 注意事项(针对流) 字节流和字符流是互斥的. tomcat会帮我们关闭流 验证码: 作用:防止恶意暴力破解密码
1 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2 // 使用java图形界面技术绘制一张图片
3
4 int charNum = 4;
5 int width = 30 * 4;
6 int height = 30;
7
8 // 1. 创建一张内存图片
9 BufferedImage bufferedImage = new BufferedImage(width, height,
10 BufferedImage.TYPE_INT_RGB);
11
12 // 2.获得绘图对象
13 Graphics graphics = bufferedImage.getGraphics();
14
15 // 3、绘制背景颜色
16 graphics.setColor(Color.YELLOW);
17 graphics.fillRect(0, 0, width, height);
18
19 // 4、绘制图片边框
20 graphics.setColor(Color.BLUE);
21 graphics.drawRect(0, 0, width - 1, height - 1);
22
23 // 5、输出验证码内容
24 graphics.setColor(Color.RED);
25 graphics.setFont(new Font("宋体", Font.BOLD, 20));
26
27 // 随机输出4个字符
28 Graphics2D graphics2d = (Graphics2D) graphics;
29 String s = "ABCDEFGHIGKLMNOPQRSTUVWXYZ01234567890";
30 Random random = new Random();
31
32 String msg="";
33 int x = 5;
34 for (int i = 0; i < 4; i++) {
35 int index = random.nextInt(26);
36 String content = String.valueOf(s.charAt(index));
37 msg+=content;
38 double theta = random.nextInt(45) * Math.PI / 180;
39 graphics2d.rotate(theta, x, 18);
40 graphics2d.drawString(content, x, 18);
41 graphics2d.rotate(-theta, x, 18);
42 x += 30;
43 }
44
45 // 6、绘制干扰线
46 graphics.setColor(Color.GRAY);
47 for (int i = 0; i < 5; i++) {
48 int x1 = random.nextInt(width);
49 int x2 = random.nextInt(width);
50
51 int y1 = random.nextInt(height);
52 int y2 = random.nextInt(height);
53 graphics.drawLine(x1, y1, x2, y2);
54 }
55
56 // 释放资源
57 graphics.dispose();
58
59 // 图片输出 ImageIO
60 ImageIO.write(bufferedImage, "jpg", response.getOutputStream());
61
62
63 }
3,Request 请求.若想获取请求信息,找我就可以了 请求的格式: 请求行 请求头 请求体 (1)api简介 a,请求行 格式:请求方式 资源路径 协议/版本 例如:GET /augmentum/1.html HTTP/1.1 常用方法: getMethod() getRequestURI() getProtocol() getQueryString() b, 请求头 格式: key:name1[,name2] 常用方法: String getHeader(key) Enumeration getHeaders(key) Enumeration getHeaderNames(); getIntHeaders(key) c, 请求体 只有post才有请求体,存放就是post请求的参数 例如 username=tom&password=123&hobby=eat&hobby=sleep 常用方法: String getParameter(key) Enumeration getParameterNames() Map<String,String[]> getParameterMap(); String[] getParameterValues(key); (2)api详解 a,请求行: 常用方法: getMethod():获取请求的方式 getRequestURI():获取的从项目名开始到请求参数参数之前(?) getProtocol():获取协议和版本 getQueryString():以字符串的形式获取请求参数 结果: GET /augmentum/row HTTP/1.1 login=tom&password=123 GET /augmentum/form.html HTTP/1. 常见的请求方式:post和get 区别: 1.get请求的参数会出现在地址栏上,post不会,post相对安全 2.get请求参数的大小有限制,post理论上没有. 3.只有post有请求体. 获取用户信息: getRemoteAddr():获取用户ip getRequestURL():获取请求路径(带协议的路径 URL) getContextPath():获取项目名 结果: 192.168.40.1xx http://192.168.40.97/augmentum/row /augmentum
1 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
2 /*//获取请求方式
3 String method = request.getMethod();
4 System.out.println(method);
5 //获取请求资源路径
6 String uri = request.getRequestURI();
7 System.out.println(uri);
8 //获取协议版本
9 String pro = request.getProtocol();
10 System.out.println(pro);
11 //获取get请求的请求参数
12 String s = request.getQueryString();
13 System.out.println(s);*/
14
15 //获取用户ip
16 String addr = request.getRemoteAddr();
17 System.out.println(addr);
18 //获取请求路径
19 String url = request.getRequestURL().toString();
20 System.out.println(url);
21 //获取项目名
22 String contextPath = request.getContextPath();
23 System.out.println(contextPath);
24 }
b,请求头: 格式: key:name1[,name2] 常用方法: String getHeader(key):获取指定的头信息 int getIntHeader(key): long getDateHeader(key): Enumeration getHeaders(key):以Enumeration形式获取指定头的信息 Enumeration getHeaderNames();返回所有的请求头的名称 防盗链 使用的 referer请求头
String referer = request.getHeader("referer");
if (referer==null) {
System.out.println("地址栏来的 可以访问");
}else if(referer.startsWith("http://localhost/augmentum")){
System.out.println("站内访问");
}else{
System.out.println("站外访问");
}
}
c,请求体: 只有post请求才有,用来存放请求参数. get请求和post通用的方法: 获取用户参数: String getParameter(key):获取指定的参数信息 String[] getParameterValues(key):以string[]的格式返回指定的参数信息 Map<String,String[]> getParameterMap();以map的形式返回所有的参数 Enumeration getParameterNames();以Enumeration形式返回所有的参数名称 例如: 姓名:tom 爱好:[drink, sleep] ---------------------- username:[tom] password:[1234] hobby:[drink, sleep] ---------------------- username:[tom] password:[1234] hobby:[drink, sleep]
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取姓名
String username = request.getParameter("username");
System.out.println("姓名:"+username);
//获取爱好
String[] hobby=request.getParameterValues("hobby");
System.out.println("爱好:"+Arrays.toString(hobby));
//获取所有
System.out.println("----------------------");
Map<String,String[]> map=request.getParameterMap();
for (String name : map.keySet()) {
System.out.println(name+":"+Arrays.toString(map.get(name)));
}
System.out.println("----------------------");
//获取所有的参数名称
Enumeration<String> params = request.getParameterNames();
while(params.hasMoreElements()){
String name = params.nextElement();
System.out.println(name+":"+Arrays.toString(request.getParameterValues(name)));
}
}
d,域对象: request: 一次请求中,响应之前. 请求串,请求链 request.getRequestDispatcher("转发路径").forward(request,response) 服务器内部跳转 客户端的路径: /工程名/编写的路径 服务器的内部路径: /编写的路径 常用方法: xxxAttribute() setAttribute(String,Object); Object getAttribute(String) removeAttribute()
请求转发与重定向的区别 1.请求转发是服务器内部跳转,地址栏不会发生改变 重定向地址栏会发生改变。
2.请求转发,只有一次请求,一次响应. 重定向,有两次请求,两次响应。
3.请求转发存在request域,可以共享数据. 重定向不存在request域。
4.请求转发只能在服务器的内部跳转,简单说,只能访问本站内资源。 重定向可以访问站外资源,也可以访问站内资源.
5.请求转发是由request 发起的 . request.getRequestDispatcher().forward() 重定向是由response 发起的 response.sendRedirect();
6.请求转发与重定向时路径写法不一样. 重定向要跳转的路径是从浏览器在次发起的,是浏览器端路径,写法: /工程名/资源 请求转发是服务器内部跳转,这时它与浏览器无关 写法:/资源 可用如下图来表示:
请求的中文乱码: 浏览器地址栏使用utf-8编码 tomcat7使用的iso8859-1编码 参数使用utf-8编码,tomcat使用iso-8859-1进行解码出现了乱码. 解决的思路: 把接受的参数先iso-8859-1编码,然后使用utf-8进行解码 对于post请求和get请求可以通过 new String(name.getBytes("iso8859-1"),"utf-8"); 对于post请求还可以使用 request.setCharacterEncoding("utf-8"); 乱码解决过程 String s="赵四"; String s1=URLEncoder.encode(s,"utf-8"); String s2=URLDecoder.decode(s1, "iso8859-1"); System.out.println(s2); //先使用iso8859-1编码 String s3 = URLEncoder.encode(s2, "iso8859-1"); //使用utf-8解码 String s4 = URLDecoder.decode(s3, "utf-8"); System.out.println(s4);