【JavaEE学习笔记】Servlet_03_重定向,请求对象,请求域

Servlet_03

A.重定向

1.概述

浏览器请求服务器,服务器通过HTTP协议约定响应头去告诉浏览器,并实现请求

状态码:302

2.特点

a.两次请求,两次响应

b.地址栏会发生变化

c.可以跳转到外部站点资源,也可以跳转到内部站点的资源

3.方法

a.方式1

response.setStatus(302);设置状态码

response.setHeader("location", "网址");设置头,跳转外部网址

response.setHeader("location", "内部文件");设置头,跳转内部资源

b.方式2

response.sendRedirect("跳转地址");

package org.xxxx.demo;

import java.io.IOException;

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

public class Demo01 extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 设置状态码
		response.setStatus(302);

		// 方式1
		// 设置头
		// response.setHeader("location", "http://wwww.baidu.com");
		// 访问内部资源 /工程名/跳转的文件地址
		// response.setHeader("location", "/MyServletDemo/index.jsp");
		
		// 方式2
		response.sendRedirect("http://www.baidu.com");
	}

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

}
在浏览器请求地址,会发现,跳转到百度,并且地址栏发生变化

跳转后


B.请求对象request

1.获取请求行

request.getMethod();获取请求的方式

request.getRequestURI();获取URI(其实就是个相对路径:工程名/虚拟地址)

request.getRequestURL();获取URL(全路径:http://ip/URI)

request.getProtool();获取协议版本

request.getRemoteAddr();获取ip

request.getRemoteHost();获取主机名

request.getRemotePort();获取端口

package org.xxxx.demo;

import java.io.IOException;

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

public class Demo01 extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 获取请求方式
		String method = request.getMethod();
		
		// 获取URI
		String uri = request.getRequestURI();
		
		// 获取URL
		StringBuffer url = request.getRequestURL();
		
		// 获取协议版本
		String protocol = request.getProtocol();
		
		// 获取ip
		String ip = request.getRemoteAddr();
		
		// 获取主机名
		String host = request.getRemoteHost();
		
		// 获取端口
		int port = request.getRemotePort();
		
		System.out.println(method);
		System.out.println(uri);
		System.out.println(url);
		System.out.println(protocol);
		System.out.println(ip);
		System.out.println(host);
		System.out.println(port);
		
	}

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

}


2.获取请求头

request.getHeader("user-agent");获取请头的值(可以查看浏览器版本)

request.getDateHeader(name);获取日期头

request.getIntHeader(name);获取数字头

package org.xxxx.demo;

import java.io.IOException;

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

public class Demo01 extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 获取请求头的值
		String browser = request.getHeader("user-agent");
		
		System.out.println(browser);
	}

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

}

3.处理请求(解决中文乱码)

处理表单提交后台的数据

a.处理get请求

get请求参数拼接在URL后面,通过getQueryString();获取请求参数

获取的是浏览器进行了一个URLEncode()编码后的值

要通过URLDecoder.decode();进行编码,否则会出现中文乱码

b.处理post请求

post请求把请求参数封装在请求体里面

通过request.getReader().readLine();获取

然后通过decode进行编码

c.验证

在index.jsp中写一个表单,提交用户名(中文)和密码

观察控制台获取的参数

package org.xxxx.demo;

import java.io.IOException;
import java.net.URLDecoder;

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

public class Demo01 extends HttpServlet {
	// get请求
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 获取请求参数 中文会得到一个类似于%E5%BC%A0%E4%B8%89的乱码
		String line = request.getQueryString();

		// 通过decode进行编码 username=张三&password=123456
		line = URLDecoder.decode(line, "utf-8");

		// 获取信息
		// 截取&
		String[] split = line.split("&");
		// 截取=获取信息
		String username = split[0].split("=")[1];
		String password = split[1].split("=")[1];

		System.out.println(username + "---" + password);
	}

	// post请求
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 从请求体中获取处参数
		String line = request.getReader().readLine();

		// 转码 username=张三&password=123456
		line = URLDecoder.decode(line, "utf-8");

		// 获取信息
		// 截取&
		String[] split = line.split("&");
		// 截取=获取信息
		String username = split[0].split("=")[1];
		String password = split[1].split("=")[1];

		System.out.println(username + "---" + password);
	}

}
index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">

<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
</head>

<body>
	<form action="/MyServletDemo/demo01" method="get">
		<center>
			<input type="text" name="username" placeholder="请输入用户名" /><br>
			<input type="password" name="password" placeholder="请输入密码" /><br>
			<input type="submit" value="登录" />
		</center>
	</form>
</body>
</html>

控制台结果


4.this.doGet()的由来

优化上一部的代码,将重复代码封装成一个方法

并且在判断是否是get/post的时候,也封装到方法中

这样一来,两个方法里都是调用方法,那在doPost()中调用doGet()即可

package org.xxxx.demo;

import java.io.IOException;
import java.net.URLDecoder;

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

public class Demo01 extends HttpServlet {
	// get请求
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		getParment(request, response);
	}

	// post请求
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}

	public void getParment(HttpServletRequest request, HttpServletResponse response) throws IOException {
		// 获取方式
		String method = request.getMethod();

		String line = null;

		if (method.equals("GET")) {
			// 获取请求参数 中文会得到一个类似于%E5%BC%A0%E4%B8%89的乱码
			line = request.getQueryString();

			// 通过decode进行编码 username=张三&password=123456
			line = URLDecoder.decode(line, "utf-8");

		} else if (method.equals("POST")) {
			// 从请求体中获取处参数
			line = request.getReader().readLine();

			// 转码 username=张三&password=123456
			line = URLDecoder.decode(line, "utf-8");

		}

		// 获取信息
		// 截取&
		String[] split = line.split("&");
		// 截取=获取信息
		String username = split[0].split("=")[1];
		String password = split[1].split("=")[1];

		System.out.println(username + "---" + password);
	}

}

5.获取参数

针对上面封装的方法,Java提供了获取参数的方法,我们只需要进行转码就行

a.request.getParameter(key);获取参数

b.request.setCharacterEncoding("utf-8");

   request.setContentType("text/html;charset=utf-8");只能处理post

c.通过字符串方法转码(get和post方法通用)

getBytes("ISO-8859-1");解码

new String(bytes, "utf-8");编码

d.注意:

1)tomcat8.5版本,配置文件默认为utf-8

   通过该方法获取参数的请求方式为get

   则不需要转码,post需要转码

   在不知道请求方式情况下,写方式b,只对post有效

2)低版本,配置文件默认为ISO-8859-1

   通过获取post请求参数需要转码

   获取get请求参数也需要转码

   两个都需要转码,写方式c,对两者都有效

package org.xxxx.demo;

import java.io.IOException;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.Map;
import java.util.Set;

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

public class Demo01 extends HttpServlet {
	// get请求
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		// 转码1:只用于POST,适用于tomcat8.5版本
		request.setCharacterEncoding("utf-8");
		response.setContentType("text/html;charset=utf-8");

		// 获取参数 tomcat8.5版本,get方法不用转码
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		
		// 转码2:get/post方式通用,适用于tomcat低版本
		// byte[] bytes = username.getBytes("ISO-8859-1");
		// username = new String(bytes, "utf-8");

		System.out.println(username + "---" + password);

	}

	// post请求
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		this.doGet(request, response);
	}

}

6.获取参数的四种方式

a.上一条中演示的

b.针对复选框(多选)

request.getParameterValues("hobby");

		String[] values = request.getParameterValues("hobby");
		for (String v : values) {
			System.out.println(v);
		}

c.拿到所有请求参数的键和值,封装到map集合(常用)

request.getParaterMap();

Map<String, String[]> map = request.getParameterMap();
		
		// 遍历集合
		Set<String> keySet = map.keySet();
		// 遍历键
		for (String key : keySet) {
			System.out.println(key);
			String[] values = map.get(key);
			
			// 遍历值
			for (String v : values) {
				System.out.println(key + "===" + v);
			}
		}

d.获取迭代器,但多选只能获取的一个,所以不常用

		Enumeration<String> names = request.getParameterNames();
		while (names.hasMoreElements()) {
			String key = names.nextElement();
			String v = request.getParameter(key);
			System.out.println(v);
		}

C.请求域

1.request

a.是一个请求对象,用来封装请求消息

b.是一个域对象,可以在他的范围内共享数据

c.请求的范围:一次请求和一次响应之间

2.请求转发

a.request.getRequestDispatcher("/mydemo").forward(request, response);

将当前请求转向1mydemo2,不用输入工程名

b.特点

1)一次请求一次响应

2)地址栏不发生变化

3)只能访问内部站点资源

c.什么时候使用重定向?什么时候使用转发?

1)如果需要在请求的多个资源中共享数据,则使用转发

2)如一次性的数据存入请求域中

d.代码

在Demo02中设置域对象,然后请求转发到Demo03

Demo02

package org.xxxx.demo;

import java.io.IOException;

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

public class Demo02 extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// 在请求域设置一个数据
		request.setAttribute("num1", "100");
		
		this.getServletContext().setAttribute("num2", "1000");
		
		// 请求转发到/mydemo03
		request.getRequestDispatcher("/demo03").forward(request, response);
		
	}

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

}

Demo03

package org.xxxx.demo;

import java.io.IOException;

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

public class Demo03 extends HttpServlet {
	public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("收到mydemo02的转发请求");
		// 获取域对象
		String num1= (String) request.getAttribute("num1");
		// 获取全局对象
		String num2 = (String) this.getServletContext().getAttribute("num2"); 
		
		System.out.println(num1);
		System.out.println(num2);
	}

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

}

在浏览器请求Demo02的地址


观察控制台输出的是Demo03的值


3.路径的书写

a.请求转发时,只用写/虚拟路径

b.重定向和网页上请求服务器时,要写/项目名/虚拟路径

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值