servlet response获取 setcookie_Servlet技术之八:Servlet的请求响应处理

Request对象:

问题:

浏览器发起请求到服务器,会遵循HTTP协议将请求数据发送给服务器。那么服务器接受到请求的数据该怎么存储呢?不但要存,而且要保证完成性。

解决:

使用对象进行存储,服务器每接受一个请求,就创建一个对象专门的存储此次请求的请求数据。

实现:

request对象

解释:

服务器接收到浏览器的请求后,会创建一个Request对象,对象中存储了此次请求相关的请求数据。服务器在调用Servlet时会将创建的Request对象作为实参传递给Servlet的方法,比如:service方法。

特点:

1.request对象有服务器创建

2.一次请求创建一个request对象

3.生命周期为一次请求内,请求结束即销毁此次请求的request对象

package com.bj.servlet;

import java.io.IOException;
import java.util.Enumeration;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * request对象学习之获取请求数据
 * 	请求数据:
 * 		请求行:请求方式  请求URL 协议
 * 			getMethod();		返回请求方式
 * 			getRequestURL();	返回请求URL
 * 			getRequestURI();	返回请求URI
 * 			getQueryString();	返回get请求中的URL中的用户数据 注意:post请求中没有此方法。
 * 			getSchema();		返回协议
 * 		请求头
 * 			getHeader(String name) 根据键名获取请求头信息
 * 				注意:如果获取的请求头信息不存在返回null。
 * 			getHeaderNames()  返回存储了请求头键名的枚举集合。
 * 		请求实体
 * 			getParameter(String name) 根据键名获取数据
 * 				注意:
 * 					键名其实就是前端页面中的表单标签的name属性的值或者前端页面其他方式提交数据的键的名字
 * 					如果请求中没有对应的请求数据,则返回null.
 *			getParameterValues(String name) 根据键名获取同名不同的值,返回数组
 *				注意:如果没有对应的键名,则返回null
 *			getParameterNames()  返回实体数据中键名的枚举
 *		请求网络相关数据
 *			getRemoteAddr()		获取客户端的IP地址
 *			getRemotePort()		获取客户端端口号
 *			getLocalAddr()		获取服务器端的IP
 *			getLocalPort()		获取服务器端的端口号
 * 
 */
@WebServlet("/ReqServlet")
public class ReqServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//获取请求信息
		//获取请求行信息
			//获取请求方式
				String method = req.getMethod();
				System.out.println("请求方式:"+method);
			//获取请求URL信息
				StringBuffer requestURL = req.getRequestURL();
				System.out.println("请求URL:"+requestURL.toString());
			//获取请求URI信息
				String requestURI = req.getRequestURI();
				System.out.println("请求URI:"+requestURI);
			//获取get请求URL中的请求数据
				String queryString = req.getQueryString();
				System.out.println("获取get请求URL中的数据:"+queryString);
			//获取协议
				String scheme = req.getScheme();
				System.out.println("获取请求协议:"+scheme);
		//获取请求头信息
			//根据键名获取请求头信息
				String header = req.getHeader("User-Agent");
				System.out.println("获取浏览器版本信息:"+header);
			//获取请求头中键名的枚举
					Enumeration headerNames = req.getHeaderNames();
					while(headerNames.hasMoreElements()){
						//获取请求头键名
						String name=(String) headerNames.nextElement();
						//获取请求头的键名对应的值
						String value=req.getHeader(name);
						System.out.println(name+":"+value);
					}
		//获取请求实体数据(用户数据)
			//根据键名获取数据
					String uname = req.getParameter("uname");
					String pwd=req.getParameter("pwd");
					System.out.println("请求实体数据:"+uname+":"+pwd);
			//获取同名不同值的实体数据
					String[] favs = req.getParameterValues("fav");
					if(favs!=null){
						for(String s:favs){
							System.out.println("fav的值为:"+s);
						}
					}	
			//获取请求实体中键名的枚举
					Enumeration names = req.getParameterNames();
					while(names.hasMoreElements()){
						//获取键名
						String name=(String) names.nextElement();
						//判断
						if("fav".equals(name)){
							String[] favs2=req.getParameterValues(name);
							if(favs!=null){
								for(String s:favs2){
									System.out.println(name+":"+s);
								}
							}
						}else{
							//获取值
							String value=req.getParameter(name);
							System.out.println(name+":"+value);
						}	
					}
			//请求相关的网络数据
				//获取客户端信息
					String remoteAddr = req.getRemoteAddr();
					System.out.println("获取客户端的IP:"+remoteAddr);
				//获取客户端的端口号(浏览器)
					int remotePort = req.getRemotePort();
					System.out.println("获取客户端的端口号:"+remotePort);
				//获取服务器主机IP
					String localAddr = req.getLocalAddr();
					System.out.println("获取服务器IP:"+localAddr);
				//获取服务器的端口号
					int localPort=req.getLocalPort();
					System.out.println("获取服务器端口号:"+localPort);
	//处理请求信息
	//响应处理结果
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

浏览器中输入如下内容来运行servlet:

c75e2ece4e8a8c80bb28cea3ecd07281.png

运行结果如下:

8ecbac87228d2e98633a2e7d57e210b6.png

Response对象:

问题:

在使用Request对象获取了请求数据并进行处理后,处理的结果如何显示到浏览器中呢?

解决:

使用Response对象

解释:

服务器在调用指定的Servlet进行请求处理的时候,会给Servlet的方法传递两个实参request和response。其中request中封存了请求相关的请求数据,而response则是用来进行响应的一个对象。

package com.bj.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 *resp对象之处理响应学习:
 *	设置响应行: 协议  状态码 状态消息
 *		resp.sendError(int status);
 *		作用:可以自主的响应状态给浏览器
 *	设置响应头
 *		addHeader(String name,String value) 添加响应头信息,同名数据不会覆盖
 *		setHeader(String nanme,String value) 设置响应头信息,会覆盖原有信息。如果没有此响应头则添加该信息。
 *	设置响应实体(处理结果)
 *		resp.getWriter().write("实体内容");
 *		注意:
 *			实体内容可以分开进行响应。
 * 注意:
 * 		一旦使用resp对象作出了请求响应,则意味着此次请求处理完毕。服务器在响应后会将此次请求相关的req对象和resp对象销毁。
 *
 */
@WebServlet("/ResponseServlet")
public class ResponseServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
       
    
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//获取请求数据
		//处理请求数据
		//响应处理结果
			//设置响应行
				//自定义响应404异常
						//resp.sendError(404);
			//设置响应头
					//添加响应头信息
						resp.addHeader("mouse","thinkpad");
						resp.addHeader("mouse","thinkpad2");
					//设置响应头
						//resp.setHeader("mouse", "two fly birds");
						
			//设置响应实体
					resp.getWriter().write("resp object");
					resp.getWriter().write("resp object");
					resp.getWriter().write("resp object");
					resp.getWriter().write("resp object");
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

dd62af749655be39903cd434ad2824cb.png

6553339c26b9093e842cf903ee149c85.png

代码修改如下:

//设置响应头
        //添加响应头信息
	  resp.addHeader("mouse","thinkpad");
	  resp.addHeader("mouse","thinkpad2");
	//设置响应头
	  resp.setHeader("mouse", "two fly birds");

结果如下:

d8a904f0bef3aa65e4ace82d0f8e699d.png

请求乱码问题解决:服务器获取的请求数据乱码

Get方式请求:

方式一:每个数据都要单独的进行转换

String uname = req.getParameter("uname");
String uname2 = new String(uname.getBytes("iso8859-1"),"utf-8");

方式二:

在doGet()方法中使用: req.setCharacterEncoding(“utf-8”);

在tomcat服务器目录下的conf文件下找到server.xml文件,打开进行如下配置:

4e866c8a0ae19fe19366a7a1fbf531ea.png

Post方式请求:

在doGet()方法中使用: req.setCharacterEncoding(“utf-8”);

响应乱码问题解决:浏览器中显示的服务器响应数据乱码

resp.setContentType("text/html;charset=utf-8");

流程总结:

Servlet的使用流程:

设置请求编码格式

设置响应编码格式

获取请求信息

处理请求信息

响应处理结果

数据流转流程:

浏览器------>服务器------->数据库

浏览器<------服务器<-------数据库

请求转发:

问题:

服务器在接收到浏览器的请求后,仅仅使用一个Servlet进行请求处理,会造成不同的Servlet逻辑代码冗余,Servlet的职责不明确。

解决:

使用请求转发。其实就是在一个servlet中调用其他的servlet。

特点:

1.降低了Servlet之间的代码冗余

2.一次请求转发内的Servlet共享此次请求request和response对象

3.浏览器9地址栏信息不改变。

req.getRequestDispather("请求转发的servlet的别名").forward(req,resp);

d5aff474fefc3286f1a7209279fe2bb9.png

Request对象作用域

问题:使用请求转发后,不同的Servlet之间怎么进行数据的共享呢?或者说数据怎么从一个servlet流转给另外一个Servlet呢?

解决:使用request对象的作用域

使用:

request.setAttribute(object name,Object value);
request.getAttribute(Object obj);

作用:解决了一次请求内的不同Servlet的数据(请求数据+其他数据)共享问题。

作用域:基于请求转发,一次请求中的所有Servlet共享。

注意:

使用Request对象进行数据流转,数据只在一次请求内有效。

特点:

服务器创建

每次请求都会创建

生命周期一次请求

重定向

问题:

如果当前的请求,Servlet无法进行处理怎么办?

如果使用请求转发,造成表单数据重复提交怎么办?

解决:

使用重定向

使用:

response.sendRedirect(“路径”);

本地路径为:uri

网络路径为:定向资源的URL信息

特点:

两次请求

浏览器地址栏信息改变

避免表单重复提交

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值