javaweb学习之Request与Response

Request与Response

在前面Http请求的文章中我们看到一个http请求包含请求头,请求体,响应头和响应体,那么对于这些请求方面和响应方面我们与浏览器交互标准是有了,我们后端是不是需要一个关于请求和响应的API,我们为了方便描述一个http请求出现了Request和Response概念。

cdkc11.png

Request

request这个对象不用事先声明,就可以在JSP网页中使用,在编译为Servlet之后,它会转换为javax.servlet.http.HttpServletRequest形态的对象,HttpServletRequest对象是有关于客户端所发出的请求的对象,只要是有关于客户端请求的信息,都可以由它来取得,例如请求标头、请求方法、请求参数、客户端IP,客户端浏览器等等信息

ServletRequest -- 通用request,提供一个request应该具有的最基本的方法.HttpSerletRequest是Rquest的子类针对http协议进行了进一步的增强

Request的操作

 

获取客户机信息

getRequestURL() 方法返回客户端发出请求完整URL getRequestURI() 方法返回请求行中的资源名部分 getQueryString() 方法返回请求行中的参数部分 getRemoteAddr() 方法返回发出请求的客户机的IP地址 getMethod() 得到客户机请求方式 getContextPath() 获得当前web应用虚拟目录名称

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//1.获取客户端请求的完整的url
		String url=request.getRequestURL().toString();
		System.out.println(url);
		//2.获取客户端请求的资源的部分名称 
		String uri=request.getRequestURI();
		System.out.println(uri);
		//3.获取请求行中的参数部分
		String pram=request.getQueryString();
		System.out.println(pram);
		//4.返回客户端的ip地址(*)
		String ip=request.getRemoteAddr();
		System.out.println(ip);
		//5.获取客户机的请求方式
		String method=request.getMethod();
		System.out.println(method);
		//6.获取当前web的应用的名称
		String name=request.getContextPath();
		System.out.println(name);
		
		//请求转发时以后有这个方法
		response.sendRedirect(request.getContextPath()+"/index.jsp");
	}

获取请求头信息

获得客户机请求头 getHeader(name)方法 --- String getHeaders(String name)方法 --- Enumeration枚举变量<string类型的> getHeaderNames方法 --- Enumeration 获得具体类型客户机请求头 getIntHeader(name)方法 --- int getDateHeader(name)方法 --- long(日期对应毫秒)

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//获取客户机的请求头
		//String value=request.getHeader("Host");
		//System.out.println(value);
		//遍历所有的请求头
		Enumeration<String> enument=request.getHeaderNames();
		while(enument.hasMoreElements()){
			String name=enument.nextElement();
			String values=request.getHeader(name);
			System.out.println(name+":"+values);
		}
	}

获取请求参数

request.getParameter()

​ 浏览器以什么编码来发送请求参数? 浏览器以什么编码打开的表单页面,就用什么编码发送这个页面提交的数据。服务器以什么编码来打开呢?如果不指定,则使用ISO8859-1,这样如果请求参数中有中文必然就乱码了​ 对于POST提交,可以设置request.setCharacterEncoding("utf-8");明确的通知服务器以浏览器发送过来的编码来打开数据就可以解决乱码但是上面的方法只对请求中实体内容部分起作用,所以GET提交的乱码并不能解决. 对于GET提交的乱码,只能手动的进行编解码从而解决乱码问题:​ String username = request.getParameter("username");​ username = new String(username.getBytes("iso8859-1"),"utf-8");

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		/*
		 * post提交乱码解决
		 */
		//此处也要进行对服务器编码进行设置(通知服务器以什么编码解码http请求中的实体内容)
		request.setCharacterEncoding("utf-8");
		//获取请求参数的值但是传中文字符是会转义到其他的
		String name=request.getParameter("username");
		//System.out.println(name);
		/*
		 * get提交乱码解决方式(同样也适合post提交方式)
		 * 现对提交的参数按照iso8859-1进行编码,然后在解码到其他码表转回
		 * 
		 */
			String username=new String(name.getBytes("iso8859-1"),"utf-8");
		/
		//获取到用一个枚举变量的类型;
		Enumeration<String> enumeration=request.getParameterNames();
		while(enumeration.hasMoreElements()){
			String names=enumeration.nextElement();
			String values=request.getParameter(names);
			System.out.println(names+":"+values);
		}
		
		
	}

利用请求域传递对象

  作用范围: 整个请求链上
    生命周期: 当服务器收到一个请求,创建出代表请求的request对象,request开始.当请求结束,服务器销毁代表请求的request对象,request域结束.
    作用: 在整个请求链范围内共享数据,通常我们在Servlet中处理好的数据会存入request域后请求转发到jsp页面来进行展示
 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//request作用域 全局域    getRequestDispater() 返回一个作为位于给定路径的资源资源的封装器的 RequestDispatcher 对象。
		request.setAttribute("banana", "color:yellow");
		this.getServletContext().getRequestDispatcher("/Demo2").forward(request, response);
	
		//转发到xxxjsp中
	//先要获取其中的数据ru
		String result="xxxx";
		request.setAttribute("xxx", result);
		request.getRequestDispatcher("xxx.jsp");
	}

实现请求转发和请求包含

(1)请求转发(.forward()): this.getServletContext().getRequestDispatcher("").forward(request,response); request.getRequestDispatcher("").forward(request,response);

请求转发是希望将请求交给另外一个资源执行,所以应该保证只有最后真正要执行的资源才能够输出数据,所以:
请求转发时,如果已经有数据被写入到了response的缓冲区,但是这些数据还没有被发送到客户端,则请求转发时,这些数据将会被清空.但是清空的只是响应中的实体内容部分,头信息并不会被清空.
而请求转发时已经有数据被打给了浏览器,那么再进行请求转发,不能成功,会抛出异常,原因是响应已经结束了,再转发交给其他人没意义了
在最终输出数据的Servlet执行完成后,response实体内容中的数据将会被设置为已提交的状态,再往里写数据也不会起作用

(2)请求包含(.include()):将两个资源的输出进行合并后输出多个资源同是输出 this.getServletContext().getRequestDispatcher("").include(request,response); request.getRequestDispatcher("").include(request,response);

被包含的Servlet程序不能改变响应消息的状态码和响应头,如果它里面存在这样的语句,这些语句的执行结果将被忽略常被用来进行页面布局

(3)三种资源处理方式的区别 请求重定向 response.sendRedirect(); 请求转发 request.getRequestDispatcher().forward(); 请求包含 request.getRequestDispatcher().include();

请求重定向和请求转发的区别:

请求重定向地址栏会发生变化.请求转发地址栏不发生变化.
请求重定向两次请求两次响应.请求转发一次请求一次响应.
            
如果需要在资源跳转时利用request域传递域属性则必须使用请求转发 request.getRequestDispatcher().forward();
如果希望资源跳转后修改用户的地址栏则使用请求重定向response.sendRedirect();
如果使用请求转发也可以重定向也可以,则优先使用请求转发,减少浏览器对服务器的访问次数减轻服务器的压力.

Response

response是Servlet.service方法的一个参数,类型为javax.servlet.http.HttpServletResponse。在客户端发出每个请求时,服务器都会创建一个response对象,并传入给Servlet.service()方法。response对象是用来对客户端进行响应的,这说明在service()方法中使用response对象可以完成对客户端的响应工作。

Response操作

设置编码方式

​ response.setHeader("Content-Type", "text/html;charset=utf-8");​ response.setCharacterEncoding("utf-8");​ response.getWriter().write("中国");

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//这里是一个编码过程,用的是操作系统的编码GBK;
		//浏览器打开时也是GBK的打开方式所以没有乱码
		//response.getOutputStream().write("English very so easy".getBytes());
		//这是会出现乱码,需要让浏览器也使用Utf-8编码打开才不会乱码或则用下面的方法
		//response.setHeader("Content-Type", "text/html;charset=utf-8");
		//response.getOutputStream().write("中国".getBytes("utf-8"));
		/*这时用中文又会乱码这时是只能是服务器把汉字转换为010101然后去查iso8859-1码表
		这个码表中没有中文,如果在iso8859-1找不到的话会被转换为?,然而浏览器又会用GBK打开这个编码所以会显示??
		这时要指定服务器查的码表
		*/
		//指定服务器查的码表
		response.setCharacterEncoding("gbk");
		response.getWriter().write("beijiang");
		response.getWriter().write("中国");
		//或者这样;
		response.setHeader("Content-Type", "text/html;charset=utf-8");
		response.setCharacterEncoding("utf-8");
		response.getWriter().write("中国");
		//或者这样;setContentType可以直接指定浏览器和服务器的编码方式
		response.setContentType("text/html,charset=utf-8");
		response.getWriter().write("中国");
		//或者这样SetCharacterEnconding指定服务器的编码
		//setContentType指定浏览器的编码
		response.setCharacterEncoding("utf-8");
		response.setContentType("text/html,charset=utf-8");
		response.getWriter().write("中国");
	}

设置是否缓存(缓存时间)

​ 不进行缓存的设置形式​ response.setIntHeader("Expires", -1);​ response.setHeader("Cache-control","no-cache");​ response.setHeader("Pragma","no-cache");​ 设置缓冲并设置缓存的时间​ response.setDateHeader("Expires", System.currentTimeMillis()+1000L360024*30);

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//设置缓冲的时间
		response.setDateHeader("Expires", System.currentTimeMillis()+1000L*3600*24*30);
		//这样只是读取到这样的文件但是并没有实现下载功能
		InputStream in=new  FileInputStream(this.getServletContext().getRealPath("1.jpg"));
		OutputStream out=response.getOutputStream();
		byte[]bs=new byte[1024];
		int i=0;
		i=in.read(bs);
		while(i!=-1){
			out.write(bs,0,i);
			i=in.read(bs);
		}
		in.close();
		///下载的形式应该用这个方式
	
	}

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//设置响应头信息在浏览器中不进行缓存
		response.setIntHeader("Expires", -1);
		response.setHeader("Cache-control","no-cache");
		response.setHeader("Pragma","no-cache");
		//同时设置服务器和浏览器的编码方式
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().write("当前时间是:"+new Date().toLocaleString());
	}

设置资源下载

​ 文件名中包含中文,则文件名要进行URL编码,URLEncoding.encode('啊啊.jpg','utf-8');如果不进行编码则文件名显示错误并且不可下载

​ ///下载的形式应该用这个方式 翻译:Disposition:配置

​ response.setHeader("Content-Disposition", "attachment;filename=1.jpg");

​ //这样只是读取到这样的文件但是并没有实现下载功能​ InputStream in=new FileInputStream(this.getServletContext().getRealPath("1.jpg"));

​ OutputStream out=response.getOutputStream();

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		///下载的形式应该用这个方式(Y)
		//setHeader头信息不支持中文格式所以命名不能用中文命名这样可以指定下载是所显示的名字
		//response.setHeader("Content-Disposition", "attachment;filename=美女.jpg");
		//方式一:狭隘
		//response.setHeader("Content-Disposition", "attachment;filename=butiful.jpg");
		//解决方式二:url编码可以用ascII码中的转换为url编码然后再转换为指定的编码
		response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode("美女.jpg","utf-8"));
		//这样只是读取到这样的文件但是并没有实现下载功能(N)
		InputStream in=new  FileInputStream(this.getServletContext().getRealPath("1.jpg"));
		OutputStream out=response.getOutputStream();
		byte[]bs=new byte[1024];
		int i=0;
		i=in.read(bs);
		while(i!=-1){
			out.write(bs,0,i);
			i=in.read(bs);
		}
		in.close();
	}

请求从定向

​ response.sendRedirect("/Test/index.jsp");

设置刷新跳转

​ response.setHeader("refresh", "3;url=/Test/index.jsp");​ 转发//request.getRequestDispatcher("/index.jsp").forward(request, response);​ 包含/request.getRequestDispatcher("/index.jsp").include(request, response);​ 重定向response.sendRedirect("/Test/index.jsp");

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//隔几秒刷新页面
		//response.getWriter().write(new Date().toString());
		//response.setHeader("Refresh", "1");
		//隔几秒会到主页
		//response.setCharacterEncoding("utf-8");
		//response.setHeader("Content-Type", "text/html;charset=utf-8");
		response.setContentType("text/html;charset=utf-8");
		response.getWriter().write("恭喜你注册成功 3秒后跳转页面....");
		response.setHeader("refresh", "3;url=/Test/index.jsp");
		//但是一般不会这样写会把写出的话放到html页面中
		//向newFilehtml那样进行操作可以在html中用<meta http-equiv="" content="">来模拟响应头信息
	}

    getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。  
    response中获取的输出流,在service方法结束后服务器会帮我们关闭,所以一般不要自己在Servlet中关闭这个流.在请求重定向时在两个不同的界面时,是可以的同时使用

    

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kay三石 [Alay Kay]

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值