web开发(七)Request对象、防盗链、中文乱码、Request域对象

1 Request对象

1.1 Request概述

什么是Request

开发的软件都是B/S结构软件,从浏览器向服务器提交一些数据,将这些内容进行封装就封装成了一个请求对象(Request对象)。
Request对象获取客户端的请求数据, 最顶层的接口是ServletRequest,而我们用的是它的子接口HttpServletRequest继承ServletRequest.

HttpServletRequest接口的实现类是Tomcat引擎提供。

1.2 Request对象的API

获得客户端信息

方法 返回值 描述
getMethod() String 获取请求的方法(Get / Set)
getQueryString() String 获取请求路径后的提交参数的字符串
getRequestURI() String 获取请求路径的URI
getRequestURL() StringBuffer 获取请求路径的URL
getRemoteAddr() String 获取客户端的IP地址
getContextPath() String 获取WEB应用名称

演示代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h1>get请求方式</h1>
    <form action="/day12_web/line2" method="get">
        用户名:<input type="text" name="username" placeholder="请输入用户名"/><br />
        密码:<input type="password" name="password" placeholder="请输入密码"/><br />
        请选择您的爱好:
           吃饭<input type="checkbox" name="check" value="eat" />
           睡觉<input type="checkbox" name="check" value="sleep" />
           打豆豆<input type="checkbox" name="check" value="hitbeanbean" /><br />
        <input type="submit" value="提交"/>
    </form>
    <h1>post请求方式</h1>
    <form action="/day12_web/line2" method="post">
        用户名:<input type="text" name="username" placeholder="请输入用户名"/><br />
        密码:<input type="password" name="password" placeholder="请输入密码"/><br />
        请选择您的爱好:
        吃饭<input type="checkbox" name="check" value="eat" />
        睡觉<input type="checkbox" name="check" value="sleep" />
        打豆豆<input type="checkbox" name="check" value="hitbeanbean" /><br />
        <input type="submit" value="提交"/>
    </form>
</body>
</html>
/**
 * Request对象获得客户机信息
 */
 @WebServlet(urlPatterns = "/line2")
public class RequestDemo1 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		
		// 获得请求方式:
		System.out.println("请求方式:"+request.getMethod());
		
		// 获得客户机的IP地址:
		System.out.println("客户机IP地址:"+request.getRemoteAddr());
		
		// 获得请求参数的字符串
		System.out.println("请求参数的字符串:"+request.getQueryString());
		
		// 获得请求路径的URL和URI
		System.out.println("请求路径的URL:"+request.getRequestURL());
		System.out.println("请求路径的URI:"+request.getRequestURI());

        // 获取WEB应用名称(重点)
        System.out.println("WEB名称为:"+request.getContextPath());	//  "WEB名称为:/day12_web
		
	}

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

利用获取WEB应用名称的方法,可以将重定向的地址写成不是固定的,方便之后调用。例如:

response.sendRedirect(request.getContextPath()+"/servlet2");

在这里插入图片描述

获得请求头的方法

方法 返回值 描述
getHeader(String name) String 获得一个key对应一个value的请求头
getHeaders(String name) Enumeration 获得一个key对应多个value的请求头

代码演示:

/**
 * Request对象获得请求头的方法
 */
@WebServlet(urlPatterns = "/line2")
public class RequestDemo1 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 获得请求头的信息
		System.out.println("获得客户机浏览器类型:"+request.getHeader("User-Agent"));
	}

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

请求头里面有个键——referer。其对应的值是:上一个页面的来源。利用这个可以做防盗链

String referer = request.getHeader("referer");

在这里插入图片描述

获得请求参数的方法(非常重要)

方法 返回值 描述
getParameter(“表单中的name值”) String 获得提交的参数(一个name对应一个value)
getParameterValues(“表单中的name值”) String[] 获得提交的参数(一个name对应多个value) 一键多值
getParameterMap() Map 获得提交的参数,将提交的参数名称和对应值存入到一个Map集合中

代码演示

  • 静态页面
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <h1>request接收表单参数</h1>
        <form action="/web01/RequestDemo2" method="post">
            用户名:<input type="text" name="username"/><br/>
            密码:<input type="password" name="password"><br/>
            性别:<input type="radio" name="sex" value="man"/><input type="radio" name="sex" value="woman"/><br/>
            籍贯:<select name="city">
            <option value="beijing">北京市</option>
            <option value="shanghai">上海市</option>
            <option value="shenzhen">深圳市</option>
            </select><br/>
            爱好:<input type="checkbox" name="hobby" value="basketball"/>篮球
            <input type="checkbox" name="hobby" value="football"/>足球
            <input type="checkbox" name="hobby" value="volleyball"/>排球<br/>
            自我介绍:<textarea name="info" rows="3" cols="8"></textarea><br/>
            <input type="submit" value="提交">
        </form> 
    </body>
</html>
  • servlet
/**
 * Request接收表单参数
 */
 @WebServlet(urlPatterns = "/RequestDemo2")
public class RequestDemo2 extends HttpServlet {

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 接收用户名和密码:
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		// 接收性别和籍贯:
		String sex = request.getParameter("sex");
		String city = request.getParameter("city");
		// 接收爱好:
		String[] hobby = request.getParameterValues("hobby");
		// 接收自我介绍
		String info = request.getParameter("info");
		System.out.println("用户名:"+username);
		System.out.println("密码:"+password);
		System.out.println("性别:"+sex);
		System.out.println("籍贯:"+city);
		System.out.println("爱好:"+Arrays.toString(hobby));
		System.out.println("自我介绍:"+info);
		
		// 使用getParameterMap接收数据:
		Map<String, String[]> map = request.getParameterMap();
		for (String key:map.keySet()) {
			String[] value = map.get(key);
			System.out.println(key+"    "+Arrays.toString(value));
		}
	}

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

1.3 Request对象接收表单请求参数的中文乱码处理

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Insert title here</title>
    </head>
    <body>
        <h1>request接收中文数据</h1>
        <h3>POST方式接收中文</h3>
        <form action="/web01/RequestDemo3" method="post">
            姓名:<input type="text" name="name"/><br/>
            <input type="submit" value="提交">
        </form>

        <h3>GET方式接收中文</h3>
        <form action="/web01/RequestDemo3" method="get">
            姓名:<input type="text" name="name"/><br/>
            <input type="submit" value="提交">
        </form>
    </body>
</html>

POST方式接收中文

  • 产生乱码的原因:
    • post方式提交的数据是在请求体中,request对象接收到数据之后,放入request的缓冲区中。缓冲区就有编码(默认ISO-8859-1:不支持中文).
  • 解决方案:
    • 将request的缓冲区的编码修改了即可。
/**
 * 演示post方式处理中文乱码
 */
 @WebServlet(urlPatterns = "/RequestDemo3")
public class RequestDemo3 extends HttpServlet {

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

        // 设置缓冲区的编码
        request.setCharacterEncoding("UTF-8");
        //接收数据
        String name = request.getParameter("name");
        System.out.println("姓名:"+name);
    }
}

GET方式接收中文

  • 产生乱码原因:
    • get方式提交的数据在请求行的url后面,在地址栏上其实就已经进行了一次URL的编码了。
  • 解决方案:
    • 将存入到request缓冲区中的值以ISO-8859-1的方式获取到,以UTF-8的方式进行解码。
 @WebServlet(urlPatterns = "/RequestDemo3")
public class RequestDemo3 extends HttpServlet {
    /**
	 * 演示get方式处理中文乱码
	 */
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 接收数据:
        // request.setCharacterEncoding("UTF-8");
       
        String name = request.getParameter("name");
        /*
        String encode = URLEncoder.encode(name, "ISO-8859-1");
		String decode = URLDecoder.decode(encode, "UTF-8");
		System.out.println("姓名:"+decode);
		*/
      
      	//在tomcat8之后,get方式的请求已经支持中文,所以不用再手动的这是编码.
        String value = new String(name.getBytes("ISO-8859-1"),"UTF-8");
        System.out.println("姓名:"+value);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       
    }
}
若要输出的数据有中文,那么在取出数据之前,一定要先设置中文的字符集。若取出来之后再设置,就还是用的默认的字符集。就会出现乱码的现象。
tomcat版本:8.5及以上版本
GET请求方式,request对象使用的字符集默认为utf-8
POST请求方式,request对象使用的字符集默认为ISO8859-1
解决:
	设置request对象的字符集为utf-8
	request.setCharacterEncoding("utf-8");
tomcat版本:8.5以下版本(了解)
没有设置request的字符集
	GET:??????
	POST:??????
request.setCharacterEncoding("utf-8"); 只针对post方式有效
	GET:??????
	POST:你好
解决:
	request对象默认字符集ISO8859-1
		1.String类中的方法:可以把获取到的ISO8859-1编码的字符串转换为字节数组
			 byte[] getBytes(Charset charset) 使用指定的字符集把字符串转换为字节数组
		2.String类的构造方法:把字节输出以UTF-8的方式解码为字符串
			String(byte[] bytes, String charsetName) 把字节数组,根据字符集转换字符串

2 Request域对象

作用域: Request域对象的作用域比较小,范围是一次请求有效

再一次请求无效

  • 域对象存储数据: setArratibute(String key, Object value)
  • 取出域对象数据: Object getAttribute(String key)
  • 移除域对象数据: removeAttribute(String key)
@WebServlet(urlPatterns = "/servlet1")
public class Demo05Servlet1 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //域对象存储数据: setArratibute(String key, Object value)
        request.setAttribute("hello","java");
        //取出域对象数据: Object getAttribute(String key)
        Object value = request.getAttribute("hello");
        System.out.println("servlet1:"+value);
    }
}

@WebServlet(urlPatterns = "/servlet2")
public class Demo06Servlet2 extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //取出域对象数据: Object getAttribute(String key)
        Object value = request.getAttribute("hello");
        System.out.println("servlet2:"+value);
    }
}

扩展:(下面是按作用域由大到小排名)

  1. ServletContext:作用域时整个web项目;即这个web项目里的所有Servlet都可以访问。
  2. Session:只要浏览器不关闭就有效。就算是访问不同的虚拟地址也可以。但只能保留30分钟。
  3. Request:只要是地址栏不变,不刷新,就有效,即只能请求一次。转发也有效。但是重定向就无效了。因为转发的地址栏不变,重定向的地址栏发生变化了。
  4. PageContext:只在jsp本页面有效。

猜你喜欢

转载自blog.csdn.net/qq_45083975/article/details/92639251