request和response

第一节 页面跳转

作为后台开发人员,我们大多时候都在接收处理用户请求,给予用户响应,为了方便操作,服务器软件将请求和响应封装成了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,其不能转向到其他的w
eb路径上去,中间传递的是自己的容器内的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

他二大爷:---》特朗普   URI

美国白宫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 
      }  
    

第一种方式:使用getParameter获取

String username = req.getParameter("username");
String password=req.getParameter("password");
String gender=req.getParameter("gender");
String[] hobby = req.getParameterValues("hobby");

User user=new User(username,password,gender,hobby);
System.out.println(user.toString());

第二种方式:使用反射进行解析

            //表单的name值和value值
		   //key  name值  value  values值
		   Map<String, String[]> parameterMap = request.getParameterMap();
		  
		   User bean = new User();
		   
		   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, User.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 (Exception 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页面跳转

​ 重定向

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

​ response.sendRedirect("");

​ 转发

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

​ request.getRequestDispatcher("").forward(request,response);

2 response对象

​ ServletResponse

​ setCharacterEncoding();

​ setConentType();

​ HttpServletResponse extends ServletResponse

​ addCookie();

​ addHeader();

3 request对象

​ ServletRequest

​ setChracterEncoding();

​ getRequestURL();

​ getRequestURI();

​ HttpServletRequest

​ getHeader()

​ getParameter();

​ …

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值