Java的request和response

守給你的承諾、 提交于 2019-12-15 12:13:21

request和response

回顾

1 什么是Servlet:小服务器程序,用Java编写的服务器端程序,主要功能在于交互式地浏览和修改数据,生成动态Web内容。

2 创建Servlet

3 配置Servlet

4 接受请求参数

5 响应数据

今日内容

1、重定向和转发
2、HTTPServletResponse的使用
3、HTTPServletRequest的使用

教学目标

1、掌握重定向和转发
2、掌握HTTPServletResponse的使用
3、熟悉HTTPServletRequest的使用

作为后台开发人员,我们大多时候都在接收处理用户请求,给予用户响应,为了方便操作,服务器软件将请求和响应封装成了request和response,我们今天就讲解两个对象的操作!

第一节 页面跳转

Java Web服务端控制页面跳转主要有两种:重定向和转发

1.1 重定向

重定请求重新定个方向转到其它位置。

实现原理:

客户浏览器发送http请求----》web服务器接受后发送302状态码响应及对应新的location给客户浏览器--》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址----》服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。

特点:

特点:
1,重定向是客户端行为。
2,重定向是浏览器做了至少两次的访问请求的。
3,重定向浏览器地址改变。
4,重定向两次跳转之间传输的信息会丢失(request范围)。
5,重定向可以指向任何的资源,包括当前应用程序中的其他资源,同一个站点上的其他应用程序中的资源,其他站点的资源。注意:传递给HttpServletResponse.sendRedirect 方法的相对URL以“/”开头,它是相对于整个WEB站点的根目录
1.2 实现重定向

html页面:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>登录页面</title>
</head>
<body>
	<div>
		<form action="/day12web1/login" method="post">
			<label>账号:</label><input name="un"/><br/>
			<label>密码:</label><input type="password" name="pw"/><br/>
			<input type="submit" value="登录"/>
		</form>
	</div>
	<h5><a href="register.html">还没账号请注册</a></h5>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>网站首页</title>
</head>
<body>
	欢迎进入xxx管理系统............
</body>
</html>

Servlet代码:

/**
 * Servlet implementation class LoginServlet
 * 实现登录信息操作
 */
@WebServlet(value="/login",initParams={@WebInitParam(name="version",value="v10")})
public class LoginServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    /**
     * @see HttpServlet#HttpServlet()
     */
    public LoginServlet() {
        super();
        // TODO Auto-generated constructor stub
    }

    @Override
    public void init(ServletConfig config) throws ServletException {
    	// TODO Auto-generated method stub
    	super.init(config);
    }
	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		//response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @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);
		//获取表单提交的用户名
		String username=request.getParameter("un");
		//获取密码
		String password=request.getParameter("pw");
		//服务端输出打印
		System.out.println("POST:用户名:"+username+"---->密码:"+password);
		//重定向.可以跳转到指定的页面
		response.sendRedirect("index.html");	
	}
}
1.3 请求转发

Servlet除了支持重定向之外还支持请求转发

转发的原理:

原理:
客户浏览器发送http请求----》web服务器接受此请求--》调用内部的一个方法在容器内部完成请求处理和转发动作----》将目标资源发送给客户。在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。

特点:

1,转发是服务器行为
2,转发是浏览器只做了一次访问请求
3,转发浏览器地址不变
4,转发两次跳转之间传输的信息不会丢失,所以可以通过request进行数据的传递
5,转发只能将请求转发给同一个WEB应用中的组件
注意:如果创建RequestDispatcher 对象时指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。
1.4 实现请求转发
package com.qf.web.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;

/**
 * Servlet implementation class RegisterServlet 
 请求转发
 */
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	/**
	 * @see HttpServlet#HttpServlet()
	 */
	public RegisterServlet() {
		super();
		// TODO Auto-generated constructor stub
	}

	/**
	 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		response.getWriter().append("Served at: ").append(request.getContextPath());
	}

	/**
	 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
	 *      response)
	 */
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 获取表单提交的用户名
		String username = request.getParameter("un");
		// 获取密码
		String password = request.getParameter("pw");
		// 服务端输出打印
		System.out.println("POST:注册:用户名:" + username + "---->密码:" + password);
		//请求转发
		request.getRequestDispatcher("/login.html").forward(request, response);
	}
}
1.5 网络路径问题

​ 路径分类 :

绝对路径: 用在不同网站之间的跳转,比如:http://www.baidu.com/aaa/1.jpg

​ **相对路径:**用在同一个网站中, aaa/1.jpg,仅限静态资源,如果页面比较多,会出现混乱。

根路径:根指定就是主机名(服务器) /day12web1/loginservlet

​ (/ 表示 http://localhost:8080/)/day12web1/loginservlet

​ 如果在浏览器中使用 / 表示 http://localhost:8080//listservlet

​ 如果是在服务器中使用 / 表示 /day12web1

第二节 response对象

在Servlet中可以使用的内置对象主要有:request、response、application、session、out(PrintWriter)。

2.1 ServletResponse简介

​ 定义辅助 servlet 将响应发送到客户端的对象。servlet 容器创建 ServletResponse 对象,并将它作为参数传递给 servlet 的 service 方法。 要发送 MIME 正文响应中的二进制数据,请使用 getOutputStream 返回的 ServletOutputStream。要发送字符数据,请使用 getWriter 返回的 PrintWriter 对象。

2.2 HttpServletResponse介绍

扩展 ServletResponse 接口以提供特定于 HTTP 的发送响应功能。例如,该接口拥有访问 HTTP 头和 cookie 的方法。 客户端向服务器发起的都是HTTP协议操作,所以我们大部分使用HttpServletResponse对象作为直接操作对象!

2.3 HttpServletResponse 常用API介绍
方法名称 作用
setStatus(int code) 设置响应状态码:200 成功 302 临时重定向 304 处理缓存 404 Not Found没有找到资源,500 服务器错误
setHeader(name,value) 设置响应信息头
setCharacterEncoding(String); 设置编码格式
setContentType(String) 设置返回数据mimetype
getWriter() 获取字符输出流
getOutputStream() 获取字节输出流
2.4 设置返回字符编码格式
  • 方案1

    response.setCharacterEncoding("utf-8");
    设置tomcat编码格式
    <html>
    	<head>
    		<meta charset="utf-8">
      		<title>xxx</title>
    	</head>
    	<body>编写返回的文本内容</body>
    </html>	
    设置浏览器解析文本内容格式  
    

    可以解决返回字符串乱码问题,但是需要将返回的字符串封装到html代码中.操作繁琐!

  • 方案2

    response.setHeader("Content-type","text/html;charset=UTF-8")
    

    方案按相对简单,通过设置响应头告知浏览器解析字符串的编码格式!

  • 方案3(推荐)

    response.setContentType("text/html;charset=UTF-8")
    

    利用setContentType这种综合性的写法解决问题!此方法也是开发中常用的方法!方便!

2.5 response练习
  1. 用户下载服务器图片

    public class DownLoadServlet extends HttpServlet {
    	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		/**
    		 * 别人访问我 我给你一张图片
    		 * 
    		 * 1.获取图片的输入流
    		 * 2.response的字节输出流
    		 */
    		//1.获取图片或者文件的输入流
    		//想要或某个文件  你必须知道绝对路径
    	    //手段: 项目中的相对路径 去获取绝对路径
    //		/吃鸡.jpg
    //		/WEB-INF/classes/吃鸡.jpg
    //		/WEB-INF/classes/com/itqf/servlet/吃鸡.jpg
    		//ServletContext getRealPath 相对路径转成绝对路径
    		String path = getServletContext().getRealPath("/吃鸡.jpg");
    		
    		System.out.println(path);
    		//文件输入流
    		FileInputStream stream = new FileInputStream(path);
    		//xx/xx/x/x/x/x/x/x/吃鸡.jpg
    	    //获取文件的名字   /
    		//File.separator  == /
    		String filename = path.substring(path.lastIndexOf(File.separator)+1);
    		//文件名编码
    		 filename =  URLEncoder.encode(filename,"UTF-8");
    		//设置响应头
    		//content-disposition", "attachment;filename="+filename 
    		//下载用的 attachment下载: filename下载文件的名字 
    		response.setHeader("content-disposition", "attachment;filename="+filename);
    		//根据文件名字的后缀名获取类型
    		String mimetype = getServletContext().getMimeType(filename);
    		response.setContentType(mimetype); //下载文件的类型
    		ServletOutputStream outputStream = response.getOutputStream();
    		byte [] buffer = new byte [8*1024];
    		int len = 0;
    		while((len=stream.read(buffer)) != -1){
    			outputStream.write(buffer, 0, len);
    		}
    		stream.close();
    	}
    }
    
  2. 页面中添加验证码

    1. 项目中添加第三方jar包validatecode.jar
    2. 创建返回验证码的servlet!
    public class CodeServlet extends HttpServlet {
    
    	/**
    		 * The doGet method of the servlet. <br>
    		 * This method is called when a form has its tag value method equals to get
    		 * @param request the request send by the client to the server
    		 * @param response the response send by the server to the client
    		 * @throws ServletException if an error occurred
    		 * @throws IOException if an error occurred
    		 */
    	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    		//1.设置生成规则
    		/**
    		 * width:验证码的宽度  px 像素
    		 * height: px
    		 * codeCount:生成验证码有几个数
    		 * lineCount:有几根线
    		 */
    		ValidateCode code = new ValidateCode(200, 50, 6, 20);
    		//2.获取生成的验证码的字符串值
    		System.out.println(code.getCode()); //获取正确值
    		//3.响应写回验证图片
    		code.write(response.getOutputStream());
    	}
    } 
    
    1. 页面中使用当前servlet
    <!DOCTYPE html>
    <html>
      <head>
        <title>login.html</title>
        <meta name="keywords" content="keyword1,keyword2,keyword3">
        <meta name="description" content="this is my page">
        <meta name="content-type" content="text/html; charset=UTF-8">
        <!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
      </head>
      <body>
          <form action="/Day11_Response1/servlet/LoginServlet"  method="post">
          	  <input type="text" name="username" placeholder="请输入账号!" />
          	  <input type="submit" value="登录"/>
          </form>
          <img src="/Day11_Response1/servlet/CodeServlet" onclick="changeCodes()" alt="验证码" title="验证码"/>
          <a href="javascript:changeCodes()" >看不清?</a>
          <script type="text/javascript">
          	function changeCodes(){
          	    var img= document.getElementsByTagName("img")[0];
          	    img.src = "/Day11_Response1/servlet/CodeServlet?r="+Math.random();
          	}
          </script>
      </body>
    </html>
    

####第三节 request对象

3.1 ServletRequest介绍

定义将客户端请求信息提供给某个 servlet 的对象。servlet 容器创建ServletRequest 对象,并将该对象作为参数传递给该 servlet 的service方法。

3.2 HttpServletRequest介绍

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

小结: 同响应相同,客户端请求协议都是基于HTTP所以我们选用HttpServletRequest来操作用户发送过来的请求的数据!

3.3 HttpServletRequest常用API

URL :Uniform Resource Location (统一资源定位符) 网址

URI :Uniform Resource Identifier (统一资源标识符) URI包含URL

美国总统:—》李学智 URI

11331401230120401203—>李学智

美国白宫10号楼99号房间–>李学智的房间 URL

//获取请求路径相关参数
**
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方法 获取输入流
3.4 获取请求数据练习
           //1.测试获取请求行数据的方法和请求头的方法
		  //1.获取请求行的方法
		   //获取请求方式
		   String method = request.getMethod();
		   //获取请求的url 
		   String url = request.getRequestURL()+"";
		   //获取uri 
		   String uri = request.getRequestURI();
		   //获取请求的参数  get
		   String query = request.getQueryString();
		   //获取请求人的ip
		   String ip = request.getRemoteAddr();
		   //获取请求的主机名
		   String host = request.getRemoteHost();
		   System.out.println(method+" url:"+url+" uri:"+
				   uri+" query:"+query+" ip:"+ip+" host:"+host);
		  //获取请求信息
		  //全部输出  
		   //post fix
		   String header = request.getHeader("user-agent");
		   if (header.contains("firefox")) {
             
		  }
		     //获取所有请求的names
		    Enumeration<String> headerNames = request.getHeaderNames();
		    while (headerNames.hasMoreElements()) {
				String name = (String) headerNames.nextElement();
				//根据name获取keys
				Enumeration<String> headers = request.getHeaders(name);
				while (headers.hasMoreElements()) {
					String key = (String) headers.nextElement();
					System.out.println(name+"--->"+key);
			   }
		 }
3.5 封装请求参数
  • 将数据封装到实体类上

    创建一个对应的实体类!

    实体类要变量命名和变量类型都有相应的要求,要求变量名跟提交参数的key相同,变量跟参数类型形同!

public class User {
 
	private String username;
	private String password;
	private String sex;
	private String [] hobby;
 	//getter/setter 
}  

​ 原生方式进行解析

            //表单的name值和value值
		   //key  name值  value  values值
		   Map<String, String[]> parameterMap = request.getParameterMap();
		  
		   JavaBean bean = new JavaBean();
		   
		   Set<Entry<String, String[]>> entrySet = parameterMap.entrySet();
		   
		   for (Entry<String, String[]> entry : entrySet) {
			//entry map中的一条
			   //username password sex
			   String key = entry.getKey();
			   String[] value = entry.getValue();
			   
			   try {
				PropertyDescriptor descriptor = 
						   new PropertyDescriptor(key, JavaBean.class);
				
				Method set = descriptor.getWriteMethod();
				
				/**
				 * 参数:哪个对象的set方法
				 * password username sex
				 */
				if (value.length == 1) {
					set.invoke(bean, value[0]);
				}else{
					set.invoke(bean, (Object)value);
				}
			
				
			} catch (IntrospectionException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
   
		  }
  • 使用Apache BeanUtils进行快速映射

    1.导入beanutils对应jar包、logging日志、commons-collections-3.2.1.jar

    2.映射

BeanUtils.populate(bean2, request.getParameterMap());	
System.out.println(bean2);

总结

1页面跳转

​ 重定向

​ 转发

2 response对象

3 request对象

作业题

1.添加登录功能,将用户登录,修改为连接数据版本
	登录成功 重定向商城页面
2.使用BeanUtils工具实现注册功能,采用Dao模式,注册成功后重定向到登录页面

面试题

1、request.getAttribute()和request.getParameter()的区别
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!