javaweb-request&response

一.Response的用法

1.作用: 

 往浏览器写东西

2.组成:

响应行  响应头 响应体

3.操作响应行

格式:
        协议/版本 状态码 状态码说明
        状态码:
            1xx:已发送请求
            2xx:已完成响应
                200:正常响应
            3xx:还需浏览器进一步操作
                302:重定向 配合响应头:location
                304:读缓存
            4xx:用户操作错误
                404:用户操作错误.
                405:访问的方法不存在
            5xx:服务器错误
                500:内部异常

3.1.设置状态码

setStatus(int 状态码):针对于 1 2 3 
了解 : sendError(int 状态码):针对于 4xx和5xx

4.操作响应头

格式:key/value(value可以是多个值)

setHeader(String key,String value):设置字符串形式的响应头
了解:setIntHeader(String key,int value):设值整形的响应头
了解:setDateHeader(String key,long value):设值时间的响应头
            
addHeader(String key,String value):添加置字符串形式的响应头 之前设置过则追加,若没有设置过则设置
 了解:addIntHeader(String key,int value):添加整形的响应头
 了解:addDateHeader(String key,long value):添加时间的响应头

常用的响应头:
            1.0location:重定向
            1.1refresh:定时刷新
            1.2content-type:设置文件的mime类型???,设置响应流的编码及告诉浏览器用什么编码打开
            1.3content-disposition:文件下载

4.1.response实现重定向

方式1:
 ★response.sendRedirect("/day10/loc2");
方式2:
 response.setStatus(302);
 respooen.setHeader("location","/day10/loc2");//设置响应头的属性 跳转到loc2

4.2.reponse实现定时刷新

方案1:    设置头 refresh 昨天做过
              response.setHeader("refresh","秒数;url=跳转的路径");
方案2:    http的meta标签(伪装成http协议)
              <meta http-equiv="refresh" content="3;url=/day10/refresh2.html">

eg:

public class RefreshServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setHeader("refresh", "5;url=http://www.baidu.com"); 

//设置头 参数 数值5为秒 中间用分号间隔 url为要跳转的网址
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

使用JS来跳转路径

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript">
	window.onload= function(){
		var time = 3;
		var second = document.getElementById("second");
		timer = setInterval(function(){
			second.innerHTML = time;
			time--;
			if(time==0){
				location.href = "http://www.baidu.com";
				clearInterval(timer);
			}
		},1000);
	}
</script>
</head>
<body>
	恭喜你,登录成功,<span id="second" style="color: red">3</span>秒后将跳转,若不跳转 请点击<a href="http://www.baidu.com">这里</a>
</body>
</html>

5.操作响应体:

1.response.getWriter():字符流

PrintWriter w=response.getWriter()://获取字符流

w.print("123");
2.ServletOutputStream getOutputStream() :字节流

注意:自己写的东西用字符流,其他一概用字节流.

5.2处理响应中文乱码:

方式1:★★★
response.setContentType("text/html;charset=utf-8");
方式2:理解
response.setHeader("content-type", "text/html;charset=utf-8");

注意:
            两个流互斥
            eg:response.getWriter ,用这个可以输出字符流eg;w.write("用户名")
            reponse.getOutputStream是不可以同时使用的
            
            
            当响应完成之后,服务器会判断一下流是否已经关闭,若没有关闭,服务器会帮我们关闭.(底层使用的缓冲流)

6.案例应用

文件下载:
    下载方式:
        1.超链接下载(用的少)
            <a href="/day10/download/day10.txt">下载 day10.txt</a>
            若浏览器能解析该资源的mime类型,则打开;若不能接下则下载;
        2.编码下载 通过servlet完成
            <a href="/day10/download?name=day10.txt">下载 day10.txt</a>
            a.设置文件的mime类型
                String mimeType=context.getMimeType(文件名)
                response.setContentType(mimeType);
                
            b.设置下载头信息 content-disposition
                response.setHeader("content-disposition", "attachment;filename="+文件名称);
                
            c.提供流
                response.getOutputStream();

扩展(验证码)了解

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CodeServlet extends HttpServlet {

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

		// 使用java图形界面技术绘制一张图片

		int charNum = 4;
		int width = 30 * 4;
		int height = 30;

		// 1. 创建一张内存图片
		BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

		// 2.获得绘图对象
		Graphics graphics = bufferedImage.getGraphics();

		// 3、绘制背景颜色
		graphics.setColor(Color.YELLOW);
		graphics.fillRect(0, 0, width, height);

		// 4、绘制图片边框
		graphics.setColor(Color.BLUE);
		graphics.drawRect(0, 0, width - 1, height - 1);

		// 5、输出验证码内容
		graphics.setColor(Color.RED);
		graphics.setFont(new Font("宋体", Font.BOLD, 20));

		// 随机输出4个字符
		Graphics2D graphics2d = (Graphics2D) graphics;
		String s = "ABCDEFGHGKLMNPQRSTUVWXYZ23456789";
		Random random = new Random();
		// session中要用到
		String msg = "";
		int x = 5;
		for (int i = 0; i < 4; i++) {
			int index = random.nextInt(32);
			String content = StrinQg.valueOf(s.charAt(index));
			msg += content;
			double theta = random.nextInt(45) * Math.PI / 180;
			// 让字体扭曲
			graphics2d.rotate(theta, x, 18);
			graphics2d.drawString(content, x, 18);
			graphics2d.rotate(-theta, x, 18);
			x += 30;
		}

		// 6、绘制干扰线
		graphics.setColor(Color.GRAY);
		for (int i = 0; i < 5; i++) {
			int x1 = random.nextInt(width);
			int x2 = random.nextInt(width);

			int y1 = random.nextInt(height);
			int y2 = random.nextInt(height);
			graphics.drawLine(x1, y1, x2, y2);
		}

		// 释放资源
		graphics.dispose();

		// 图片输出 ImageIO
		ImageIO.write(bufferedImage, "jpg", response.getOutputStream());

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

	}

}

code.html(点击切换图片)

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<img alt="验证码" src="/day10/code" title="看不清除,换一张" onclick="changeImg(this)">
</body>
<script type="text/javascript">
	function changeImg(obj){
		//操作src属性
		obj.src="/day10/code?i="+Math.random();
		//obj.src="/day10/code";
		//alert(1)
	}
</script>
</html>

效果图:

二.request的用法:

1.request概述

request是Servlet.service()方法的一个参数,类型为javax.servlet.http.HttpServletRequest。在客户端发出每个请求时,服务器都会创建一个request对象,并把请求数据封装到request中,然后在调用Servlet.service()方法时传递给service()方法,这说明在service()方法中可以通过request对象来获取请求数据。

2.组成部分:


        请求行 请求头 请求体

3.操作请求行 :

eg:GET /day10/row?username=tom&password=123 HTTP/1.1

3.1格式:


            请求方式 请求资源 协议/版本

3.2常用方法

掌握:

String getMethod():获取请求方式
String getRemoteAddr():获取ip地址
String getContextPath() :在java中获取项目名称  (/day10)

了解:

getRequestURI():获取的是 从项目名到参数之前的内容  /day10/regist
getRequestURL():获取的带协议的完整路径   http://localhost/day10/regist
String getQueryString():get请求的所有参数   username=tom&password=123
String getProtocol():获取协议和版本
                
 

4.操作请求头 

4.1

格式:key/value(value可以是多个值)

4.2

String getHeader(String key):通过key获取指定的value (一个)

了解:
Enumeration getHeaders(String name) :通过key获取指定的value(多个)
Enumeration getHeaderNames() :获取所有的请求头的名称
int getIntHeader(String key):获取整型的请求头
long getDateHeader(String key):获取时间的请求头

4.3

重要的请求头:
user-agent:浏览器内核 msie firefox chrome
referer:页面从那里来 防盗链

用法:String referer =request.getHeader("referer");

4.4

操作请求参数★★★★

get参数是放在地址栏上的

post参数是防止在请求体中的
            String getParameter(String key):获取一个值
            String[] getParameterValues(String key):通过一个key获取多个值
            Map<String,String[]> getParameterMap():获取所有的参数名称和值

<a href="/day04/param?username=tom&password=123&hobby=drink&hobby=sleep">
请求参数
</a>

点击得到的结果

        username:tom
        ---------values---------
        hobby:[drink, sleep]
        =====map=======
        username::[tom]
        password::[123]
        hobby::[drink, sleep]

4.5

请求的中文乱码:
        对于get请求:参数追加到地址栏,会使用utf-8编码,服务器(tomcat7)接受到请求之后,使用iso-8859-1解码,所以会出现乱码
        对于post请求,参数是放在请求体中,服务器获取请求体的时候使用iso-8859-1解码,也会出现乱码
        
        通用的方法:
            new String(参数.getBytes("iso-8859-1"),"utf-8");
        针对于post请求来说:只需要将请求流的编码设置成utf-8即可
            request.setCharacterEncoding("utf-8");

指定编码解码:
URLEncoder.encode(s,"utf-8");     //指定编码

URLDecoder.dencode(s1,"iso-8859-1");  //指定解码

文件下载扩展:
    中文名称的文件名下载的时候名称会出现问题
    常见的浏览器需要提供文件名称的utf-8编码
    对于火狐来说需要提供文件名称的base64编码
        方案1:使用工具类
        方案2:网上的方式(8成好使)
            new String(filename.getByte("gbk"),"iso8859-1");

5.域对象(request):


 5.1   request:


        创建:一次请求来的时候
        销毁:响应生成的时候
        作用:
        存放一次请求里面的数据
        请求转发(请求链,请求串)
            request.getRequestDispatcher("内部路径").forward(request,response);

举例:

分析:

只有一次请求,数据也只有一次,存放在request域对象中,虽然跳转了,但路径是没有变化的。

5.2 域对象的四个属性

设置和获取域属性
Object attr = request.getAttribute("attr");
request.setAttribute("key", "value");
request.removeAttribute("attr");
Enumeration<String> attributeNames = request.getAttributeNames();

6.案例实现(通过浏览器往数据库发送信息)

步骤分析:


    1.数据库和表(day05)
    2.页面(表单)
        给每个字段添加name属性
        还需修改表单提交的路径 method=post
    3.表单提交到一个servlet(RegistServlet)
    4.RegistServlet:
        操作:
            接受数据,封装成一个user
            调用UserSerivce完成保存操作  int regist(User user)
            判断结果是否符合我们预期
                若int=1; 插入成功
                若int!=1; 插入失败
            相应的提示信息在当前的servlet不做处理,将信息转发给另一个servlet展示(MsgServlet);
    5.UserService
        调用dao
    6.userdao 通过dbutils在数据库中插入一条记录.

7.请求转发和重定向区别:


    重定向发送两次请求,请求转发一次请求
    
    重定向地址栏发生该表,请求转发不变
    
    重定向是从浏览器发送,请求转发是服务器内部
    
    重定向不存在request域对象,请求转发可以使用request域对象
    
    重定向是response的方法,请求转发是request的方法
    
    重定向可以请求站外资源,请求转发不可以        

猜你喜欢

转载自blog.csdn.net/JQ210245253/article/details/89208814