Servlet笔记(2):Servlet请求对象 HttpServletRequest

版权声明:本博客所有文章均采用 CC BY 3.0 CN 许可协议。转载请注明出处! https://blog.csdn.net/u012228718/article/details/86688538


客户端浏览器发送一个请求,服务器作出一系列操作后作出一个响应,发送给客户端,完成一次Web过程过程操作。Web编程的过程就是通过分析客户需要什么信息或者进行了什么操作,然后进行一系列的处理,最后通过响应结果显示给客户。即一次请求-响应的过程

请求: HttpServletRequest 对象

客户端浏览器的请求被封装成一个HttpServletRequest对象。所有的信息包括请求的地址,请求的参数,提交的数据,上传的文件,客户端的IP地址甚至客户端操作系统都包含在HttpServletRequest对象中

HttpServletRequest 方法详解

编码信息和文档类型

  1. 编码信息:设置与获取编码信息
request.setCharacterEncoding("UTF-8") // 设置编码,统一使用 setCharacterEncodingFilter ,见文章 Filter 详解
request.getCharacterEncoding() // 获取编码方法

  1. 文档信息:设置与获取文档信息
request.getContentType() // 获取文档类型
response.setContentType("text/html") // 设置 文档类型为HTML类型。设置输出数据的类型,是Response的功能

服务器信息

  1. 服务器(Local) 各种信息
request.getLocalAddr(); //  即服务器IP
request.getLocalName(); // 即服务器名称
int localPort = request.getLocalPort(); // 服务器端口号
Locale locale = request.getLocale(); // 服务器环境.通过这个可以获取很多信息,如服务器所在国家、语言
  1. 服务器(Server)信息
// 服务器名称
String serverName = request.getServerName();
// 服务器端口
int serverPort = request.getServerPort();
  1. 服务器真实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;
}

客户端信息

  1. 客户端(Remote)信息
// 客户端IP
String remoteAddr = request.getRemoteAddr();
// 客户端端口
int remotePort = request.getRemotePort();
// 客户用户, 如果提供了Authorization头,则代表其用户部分。它代表发出请求的用户的名字。
String remoteUser = request.getRemoteUser();
  1. 客户端真实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;
}

获取请求行、请求头、消息体信息

  1. 获取请求行信息
// 协议,这里为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();
  1. 获取请求头
/**
 * 获取请求头信息
 *
 * @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);
}
  1. 获取消息体信息
// 查询字符串,即访问时 ? 后面的字符串
String queryString = request.getQueryString();
  1. 浏览器查看,对应上面的 请求行、请求头、消息体信息
  • 下面的信息也可以看出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的信息

  1. Servlet的信息
// Context路径
String contextPath = request.getContextPath();
// Servlet的路径
String servletPath = request.getServletPath();
// URL中Servlet路径之后、查询字符串之前的那部分。
String pathInfo = request.getPathInfo();
// 映射到服务器实际路径之后的路径信息。
String pathTranslated = request.getPathTranslated();
  1. 绝对路径
// 绝对路径
String path = request.getContextPath();  
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

其他信息

  1. 权限相关
// Authorization头, 权限认证的时候使用,一般不会自己用(这是一套标准)。
// 像Spring Security、apache Shiro 等权限认证框架都会用到
String authType = request.getAuthType();
// 当前授权用户的名称
Principal userPrincipal = request.getUserPrincipal();
  1. 其他
// 客户端Session的ID
String requestedSessionId = request.getRequestedSessionId();
// 获取Session信息
HttpSession session = request.getSession();
//获取CooKie信息
Cookie[] cookies = request.getCookies();
// 本Servlet运行的服务器信息
String serverInfo = this.getServletContext().getServerInfo();

测试代码,源码地址

  1. 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>
  1. 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>
  1. 源码
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;
    }
}

参考

  1. 源码地址
  2. Servlet学习笔记(四):Servlet的请求与响应

Fork me on Gitee

猜你喜欢

转载自blog.csdn.net/u012228718/article/details/86688538
今日推荐