您的位置:首页 > 编程语言 > Java开发

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

2017-10-22 19:30 1331 查看
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.重定向和网页上请求服务器时,要写/项目名/虚拟路径
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐