版权声明:本博客所有文章均采用 CC BY 3.0 CN 许可协议。转载请注明出处! https://blog.csdn.net/u012228718/article/details/86688538
文章目录
客户端浏览器发送一个请求,服务器作出一系列操作后作出一个响应,发送给客户端,完成一次Web过程过程操作。Web编程的过程就是通过分析客户需要什么信息或者进行了什么操作,然后进行一系列的处理,最后通过响应结果显示给客户。即一次请求-响应的过程
请求: HttpServletRequest
对象
客户端浏览器的请求被封装成一个HttpServletRequest
对象。所有的信息包括请求的地址,请求的参数,提交的数据,上传的文件,客户端的IP地址甚至客户端操作系统都包含在HttpServletRequest对象中
HttpServletRequest 方法详解
编码信息和文档类型
- 编码信息:设置与获取编码信息
request.setCharacterEncoding("UTF-8") // 设置编码,统一使用 setCharacterEncodingFilter ,见文章 Filter 详解
request.getCharacterEncoding() // 获取编码方法
- 文档信息:设置与获取文档信息
request.getContentType() // 获取文档类型
response.setContentType("text/html") // 设置 文档类型为HTML类型。设置输出数据的类型,是Response的功能
服务器信息
- 服务器(Local) 各种信息
request.getLocalAddr(); // 即服务器IP
request.getLocalName(); // 即服务器名称
int localPort = request.getLocalPort(); // 服务器端口号
Locale locale = request.getLocale(); // 服务器环境.通过这个可以获取很多信息,如服务器所在国家、语言
- 服务器(Server)信息
// 服务器名称
String serverName = request.getServerName();
// 服务器端口
int serverPort = request.getServerPort();
- 服务器真实IP
- Windows
InetAddress.getLocalHost().getHostAddress(); // 利用java.net.InetAddress 来获取服务器真实 IP 地址
- Linux
/**
* linux下获取服务器真实 IP
* InetAddress获取IP的方法在windows下没有问题,在Linux有问题,主要是在linux下返回的是 /etc/hosts
* 中配置的ip地址,而不是网卡的绑定地址。现在改用网卡的绑定地址
*
* @return
*/
public static String getServerIP() {
String serverIp = "";
try {
Enumeration<NetworkInterface> netInterfaces = null;
netInterfaces = NetworkInterface.getNetworkInterfaces();
while (netInterfaces.hasMoreElements()) {
NetworkInterface ni = netInterfaces.nextElement();
Enumeration<InetAddress> ips = ni.getInetAddresses();
while (ips.hasMoreElements()) {
InetAddress ip = ips.nextElement();
if (ip.isSiteLocalAddress()) {
serverIp = ip.getHostAddress();
break;
}
}
}
} catch (Exception ex) {
serverIp = "127.0.0.1";
}
return serverIp;
}
客户端信息
- 客户端(Remote)信息
// 客户端IP
String remoteAddr = request.getRemoteAddr();
// 客户端端口
int remotePort = request.getRemotePort();
// 客户用户, 如果提供了Authorization头,则代表其用户部分。它代表发出请求的用户的名字。
String remoteUser = request.getRemoteUser();
- 客户端真实IP地址
/**
* 获得用户真实IP
*
* @param request 请求对象
* @return String 真实IP地址
*/
public String getRealCusIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
获取请求行、请求头、消息体信息
- 获取请求行信息
// 协议,这里为HTTP协议
String protocol = request.getProtocol();
// 协议头,这里为Http
String scheme = request.getScheme();
// 访问的方式:Get还是Post
String method = request.getMethod();
// 用户请求的URI
String requestURI = request.getRequestURI();
// 用户请求的URL
StringBuffer requestURL = request.getRequestURL();
- 获取请求头
/**
* 获取请求头信息
*
* @param request
*/
private void getHeader(HttpServletRequest request) {
// 4-2 获取头信息 利用浏览器都可以看到
// 浏览器支持的格式,访问Accept的HTTP头
String accept = request.getHeader("accept");
// 从哪个页面单机链接到了本页
String referer = request.getHeader("referer");
// 包括操作系统及版本号、浏览器类型及版本号
String host = request.getHeader("Host");
String acceptLanguage = request.getHeader("Accept-Language");
String acceptEncoding = request.getHeader("Accept-Encoding");
String connection = request.getHeader("Connection");
String cookie = request.getHeader("Cookie");
// User Agent 信息
String userAgentStr = request.getHeader("user-agent");
System.out.println("浏览器支持的格式: " + getAccept(accept) + " |从哪个页面单机链接到了本页: " + referer + " |操作系统信息: " + getOS(userAgentStr) + " |客户端浏览器信息 " + getNavigator(userAgentStr));
// 使用开源的 UserAgentUtils 工具包
UserAgent userAgent = UserAgent.parseUserAgentString(userAgentStr);
Browser browser = userAgent.getBrowser();
System.out.println("浏览器信息 : " + browser);
OperatingSystem operatingSystem = userAgent.getOperatingSystem();
System.out.println("操作系统信息: " + operatingSystem);
}
- 获取消息体信息
// 查询字符串,即访问时 ? 后面的字符串
String queryString = request.getQueryString();
- 浏览器查看,对应上面的 请求行、请求头、消息体信息
- 下面的信息也可以看出http协议的繁琐,特别是Cookie的信息,特别重
- 很多分布式系统都会设计自己的私有协议,更加的轻量且注重交互的内容
Chrome 查看得出信息
【General】
Request URL: http://localhost:8080/requestServlet?param=query
Request Method: GET
Status Code: 200
Remote Address: [::1]:8080
Referrer Policy: no-referrer-when-downgrade
【Request Headers】
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng, ;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,ja;q=0.7
Cache-Control: max-age=0
Connection: keep-alive
Cookie: jenkins-timestamper-offset=-28800000; Idea-e846873f=b0ad7d26-ab1f-4b0f-95cb-0ed1c50bf3d9; locale=zh; rememberMe=xd5Owi0OZblXMRYwdSLv2IoYw95yvOxQqFjw4g9mTxEFL6Htj9Jpamucwg3XkbE04pSFUwUL7jgVEsy3aV7ispSBptVMFUvvUW2//5x3Rg0yKWdaGrTl6wCTEaxOUxUG7Qh2bAiyy/bjPjt1kCDPWfUCa5MrT05gSMyTI7s2ix5CMswL3QW2nu4R0Bvw4pY3YaQQ4zE4/oxaR7o1x5PF4iLQg6yyl7PP4Ce/Fh/U3rKsr3YE+f68mwD+7/kfyq1V6LSwdrdaTOKGs3fB8ke3y16AA26MD1W9aRwIx8RqxF6W5N14XQ8oqtpg98jrHW5pRK+wOCm9Xb4dQPUesriARNP0FbHULwh2w5S1ytU26eUDU2rpnLgsweDNE12ImR3i/7ez7/Fguidrk+soWD1qGJYKqeYyqN6B1ihAhN/umw0WM9PCuQUBTtLBndoCPgeDWU912rTlAwrsvO1sB0G7RmLpKz6poenYDPQ5Mb0KEMIZPNfxHo+TKekbwRsGJS1hhnlmYOxY3ABS6iGUrOQGSZeGdH4bBeNT1s194cO/n6Y31xiVks0MPhFuEnATFE7jEqi3oZSrNPHjybPU9ee7DtRyQZTVrKADOtydfOltGB/wV2s+8m4OmyWDWX+m+gRXaeiFqkDNMb5Rhee3iQoh/m4jBOfYjAK/3BG7+7svCWGMazRXO6Zs4GcmYMWpXzoKlz0weQFOaek1zP6124zjS1968YKHCpRnTVYULvrtM7C/3kQysR4TUm5JnyrtbSrdznrvsC8jTmsvnAwVV8FJJH8FKkYuaUHIAIJs+w3kxiHNf7ibAbyp3muXroE+Bg7I; Hm_lvt_82116c626a8d504a5c0675073362ef6f=1528939560,1528957763,1529377607,1529379542; _ga=GA1.1.600775327.1529394240; Hm_lvt_df863698d6887525c609d6e464867778=1529551688,1529584292; JSESSIONID=6BA33CCE37F788B54EA0A063A4E2CB31
Host: localhost:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36
【Query String Parameters】
param: query
获取请求的Servlet的信息
- Servlet的信息
// Context路径
String contextPath = request.getContextPath();
// Servlet的路径
String servletPath = request.getServletPath();
// URL中Servlet路径之后、查询字符串之前的那部分。
String pathInfo = request.getPathInfo();
// 映射到服务器实际路径之后的路径信息。
String pathTranslated = request.getPathTranslated();
- 绝对路径
// 绝对路径
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
其他信息
- 权限相关
// Authorization头, 权限认证的时候使用,一般不会自己用(这是一套标准)。
// 像Spring Security、apache Shiro 等权限认证框架都会用到
String authType = request.getAuthType();
// 当前授权用户的名称
Principal userPrincipal = request.getUserPrincipal();
- 其他
// 客户端Session的ID
String requestedSessionId = request.getRequestedSessionId();
// 获取Session信息
HttpSession session = request.getSession();
//获取CooKie信息
Cookie[] cookies = request.getCookies();
// 本Servlet运行的服务器信息
String serverInfo = this.getServletContext().getServerInfo();
测试代码,源码地址
- Pom 依赖添加
<!--2.X 版本-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!--开源的 UserAgent 工具 -->
<dependency>
<groupId>nl.bitwalker</groupId>
<artifactId>UserAgentUtils</artifactId>
<version>1.2.4</version>
</dependency>
- Web.xml 配置
<servlet>
<servlet-name>RequestServlet</servlet-name>
<servlet-class>com.learning.select2.reqandres.RequestServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestServlet</servlet-name>
<url-pattern>/requestServlet</url-pattern>
</servlet-mapping>
- 源码
public class RequestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doService(request);
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doService(request);
}
/**
* 通用业务方法
*
* @param request 请求对象
* @throws UnsupportedEncodingException
* @throws UnknownHostException
* @throws SocketException
*/
private void doService(HttpServletRequest request) throws IOException {
/** 1-编码方法 ************************************************************************/
// 1-设置编码方式,可以用时setCharacterEncodingFilter过滤器统一处理
// 设置获取 request 的编码方式
String characterEncoding = request.getCharacterEncoding();
request.setCharacterEncoding("UTF-8");
// 获取 请求内容类型
String contentType = request.getContentType();
System.out.println("编码方式: " + characterEncoding + "| 请求内容类型: " + contentType);
/** 2-获取服务器信息 ********************************************************************/
this.getServerInfo(request);
/** 3-获取客户端信息 *********************************************************************/
this.getClientInfo(request);
/** 4-获取请求信息 *********************************************************************/
// 4-1 获取本次请求的协议信息
// 协议,这里为HTTP协议
String protocol = request.getProtocol();
// 协议头,这里为Http
String scheme = request.getScheme();
System.out.println("协议: " + protocol + " | 协议头: " + scheme);
// 获取请求头信息
this.getHeader(request);
// 4-3 获取本次请求的一些基本信息
// 访问的方式:Get还是Post
String method = request.getMethod();
// 查询字符串,即访问时 ? 后面的字符串
String queryString = request.getQueryString();
// 用户请求的URI
String requestURI = request.getRequestURI();
// 用户请求的URL
StringBuffer requestURL = request.getRequestURL();
System.out.println("访问的方式: " + method + " |查询字符串,即访问时 ? 后面的字符串: " + queryString + " |用户请求的URI: " + requestURI + " |用户请求的URL: " + requestURL);
// 4-4 获取请求的Servlet的信息
// Context路径
String contextPath = request.getContextPath();
// Servlet的路径
String servletPath = request.getServletPath();
// URL中Servlet路径之后、查询字符串之前的那部分。
String pathInfo = request.getPathInfo();
// 映射到服务器实际路径之后的路径信息。
String pathTranslated = request.getPathTranslated();
/** 5-其他信息 *********************************************************************/
// 5-1 其他信息
// Authorization头, 权限认证的时候使用,一般不会自己用(这是一套标准)。
// 像Spring Security、apache Shiro 等权限认证框架都会用到
String authType = request.getAuthType();
// 当前授权用户的名称
Principal userPrincipal = request.getUserPrincipal();
// 客户端Session的ID
String requestedSessionId = request.getRequestedSessionId();
// 获取Session信息
HttpSession session = request.getSession();
//获取CooKie信息
Cookie[] cookies = request.getCookies();
// 本Servlet运行的服务器信息
String serverInfo = this.getServletContext().getServerInfo();
System.out.println("Context路径: " + contextPath + " |Servlet的路径: " + servletPath + " |本Servlet运行的服务器信息: " + serverInfo + " |客户端Session的ID: " + requestedSessionId);
}
/**
* 获取请求头信息
*
* @param request
*/
private void getHeader(HttpServletRequest request) {
// 4-2 获取头信息 利用浏览器都可以看到
// 浏览器支持的格式,访问Accept的HTTP头
String accept = request.getHeader("accept");
// 从哪个页面单机链接到了本页
String referer = request.getHeader("referer");
// 包括操作系统及版本号、浏览器类型及版本号
String host = request.getHeader("Host");
String acceptLanguage = request.getHeader("Accept-Language");
String acceptEncoding = request.getHeader("Accept-Encoding");
String connection = request.getHeader("Connection");
String cookie = request.getHeader("Cookie");
// User Agent 信息
String userAgentStr = request.getHeader("user-agent");
System.out.println("浏览器支持的格式: " + getAccept(accept) + " |从哪个页面单机链接到了本页: " + referer + " |操作系统信息: " + getOS(userAgentStr) + " |客户端浏览器信息 " + getNavigator(userAgentStr));
// 使用开源的 UserAgentUtils 工具包
UserAgent userAgent = UserAgent.parseUserAgentString(userAgentStr);
Browser browser = userAgent.getBrowser();
System.out.println("浏览器信息 : " + browser);
OperatingSystem operatingSystem = userAgent.getOperatingSystem();
System.out.println("操作系统信息: " + operatingSystem);
}
/**
* 获取客户端基本信息
*
* @param request
*/
private void getClientInfo(HttpServletRequest request) {
// 远程IP,即客户端IP
String remoteAddr = request.getRemoteAddr();
// 远程端口,即客户端端口
int remotePort = request.getRemotePort();
// 远程用户,如果提供了Authorization头,则代表其用户部分。它代表发出请求的用户的名字。
String remoteUser = request.getRemoteUser();
System.out.println("客户端IP: " + remoteAddr + " |客户端端口: " + remotePort + " |远程用户: " + remoteUser);
// 客户端的IP,往往会有代理,所以一般的获取方法,需要处理信息
//真实客户端IP地址
String realCusIp = getRealCusIpAddr(request);
System.out.println("客户端真实IP,附带代理的IP地址: " + realCusIp);
}
/**
* 获取服务器信息
*
* @param request
* @throws UnknownHostException
*/
private void getServerInfo(HttpServletRequest request) throws UnknownHostException {
// 2-0-基本的获取服务器信息
// 本地IP, 即服务器IP
String localAddr = request.getLocalAddr();
// 本地名称, 即服务器名称
String localName = request.getLocalName();
// 本地端口号, 即服务器端口号
int localPort = request.getLocalPort();
// 本地环境,服务器环境.通过这个可以获取很多信息
Locale locale = request.getLocale();
// 语言环境
String localeLanguage = this.getLocaleLanguage(locale);
// 国家
String localCountry = locale.getCountry();
System.out.println(" |服务器IP: " + localAddr + " |服务器名称: " + localName + " |端口号: " + localPort + " |用户的语言环境: " + localeLanguage + " |国家: " + localCountry);
// 服务器名称
String serverName = request.getServerName();
// 服务器端口
int serverPort = request.getServerPort();
System.out.println("服务器名称: " + serverName + " |服务器端口: " + serverPort);
// 2-1 实际项目中,一般会用到 java.net 包下 InetAddress 来获取服务器的真实 IP 地址
// 本地地址,服务器IP地址
String myLocalIp = InetAddress.getLocalHost().getHostAddress();
System.out.println("利用java.net包下 InetAddress 来获取服务器真实 IP 地址: " + myLocalIp);
// 2-2 Linux 获取服务器的真实 IP 地址
String serverIP = getServerIP();
System.out.println("Linux下 来获取服务器真实 IP 地址: " + serverIP);
}
/**
* linux下获取服务器真实 IP
* InetAddress获取IP的方法在windows下没有问题,在Linux有问题,主要是在linux下返回的是 /etc/hosts
* 中配置的ip地址,而不是网卡的绑定地址。现在改用网卡的绑定地址,可以取到本机的ip地址:
*
* @return
*/
public static String getServerIP() {
String serverIp = "";
try {
// InetAddress获取IP的方法在windows下没有问题,在Linux有问题(下只是读取/etc/hosts下的配置)
Enumeration<NetworkInterface> netInterfaces = null;
netInterfaces = NetworkInterface.getNetworkInterfaces();
while (netInterfaces.hasMoreElements()) {
NetworkInterface ni = netInterfaces.nextElement();
Enumeration<InetAddress> ips = ni.getInetAddresses();
while (ips.hasMoreElements()) {
InetAddress ip = ips.nextElement();
if (ip.isSiteLocalAddress()) {
serverIp = ip.getHostAddress();
break;
}
}
}
} catch (Exception ex) {
serverIp = "127.0.0.1";
}
return serverIp;
}
/**
* 用户的语言环境
*
* @param locale
* @return 语言环境名称
*/
private String getLocaleLanguage(Locale locale) {
if (Locale.SIMPLIFIED_CHINESE.equals(locale)) {
return "简体中文";
}
if (Locale.TRADITIONAL_CHINESE.equals(locale)) {
return "繁体中文";
}
if (Locale.ENGLISH.equals(locale)) {
return "英文";
}
if (Locale.JAPANESE.equals(locale)) {
return "日文";
}
return "未知语言环境";
}
/**
* @param accept
* @return 客户端浏览器接受的文件类型
*/
private String getAccept(String accept) {
StringBuffer buffer = new StringBuffer();
if (accept.contains("image/gif")) {
buffer.append("GIF 文件, ");
}
if (accept.contains("image/x-xbitmap")) {
buffer.append("BMP 文件, ");
}
if (accept.contains("image/jpeg")) {
buffer.append("JPG 文件, ");
}
if (accept.contains("application/vnd.ms-excel")) {
buffer.append("Excel 文件, ");
}
if (accept.contains("application/vnd.ms-powerpoint")) {
buffer.append("PPT 文件, ");
}
if (accept.contains("application/msword")) {
buffer.append("Word 文件, ");
}
return buffer.toString().replaceAll(", $", "");
}
/**
* 客户端浏览器信息
*
* @param userAgent
* @return String
*/
private String getNavigator(String userAgent) {
if (userAgent.indexOf("TencentTraveler") > 0) {
return "腾讯浏览器";
}
if (userAgent.indexOf("Maxthon") > 0) {
return "Maxthon浏览器";
}
if (userAgent.indexOf("MyIE2") > 0) {
return "MyIE2浏览器";
}
if (userAgent.indexOf("Firefox") > 0) {
return "Firefox浏览器";
}
if (userAgent.indexOf("MSIE") > 0) {
return "IE 浏览器";
}
if (userAgent.indexOf("Chrome") > 0) {
return "Chrome 浏览器";
}
return "未知浏览器";
}
/**
* 客户端操作系统
*
* @param userAgent
* @return String
*/
private String getOS(String userAgent) {
if (userAgent.indexOf("Windows NT 5.1") > 0) {
return "Windows XP";
}
if (userAgent.indexOf("Windows 98") > 0) {
return "Windows 98";
}
if (userAgent.indexOf("Windows NT 5.0") > 0) {
return "Windows 2000";
}
if (userAgent.indexOf("Linux") > 0) {
return "Linux";
}
if (userAgent.indexOf("Unix") > 0) {
return "Unix";
}
if (userAgent.indexOf("Windows NT 6.1") > 0) {
return "Windows 7";
}
if (userAgent.indexOf("Windows NT 10.0") > 0) {
return "Windows 10";
}
return "未知";
}
/**
* 获得用户真实IP
*
* @param request 请求对象
* @return String 真实IP地址
*/
public String getRealCusIpAddr(HttpServletRequest request) {
String ip = request.getHeader("x-forwarded-for");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}