[Java][Servlet] 取得IP、Accept、User-Agent、語言環境

這篇提及關於
Accept:  取得網頁接受類形,或是上傳檔案時可以指定用哪種類型等
User-Agent: 取得作業系統、瀏覽器名稱
Locale: 取得客戶端使用的語言環境
取得 IP 等


一、呈現結果
二、程式碼



不知道如何開專案,使用Eclipse、Servlet等
可以看之前的文章,有詳細、一步一步做不難

一、呈現結果



二、程式碼

Project 類型: Dynamic Web Project
Project 名稱: servlet
Package 名稱: idv.ycc.servlet
Class 類型: Servlet
Class 名稱: RequestServlet.java

如果是直接 Copy 程式碼請記得要用上述的名稱!


package idv.ycc.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.security.Principal;
import java.util.Locale;
import javax.servlet.FilterChain;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/RequestServlet")
public class RequestServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
    public RequestServlet() {
        super();
    }
    //取得 client 瀏覽器接受的內容類型
    private String getAccept(String accept) {
        StringBuffer buffer = new StringBuffer();
        if(accept.indexOf("image/gif") > -1)                     buffer.append("GIF 文件, ");
        if(accept.indexOf("image/x-xbitmap") > -1)               buffer.append("BMP 文件, ");
        if(accept.indexOf("image/jpeg") > -1)                    buffer.append("JPG 文件, ");
        if(accept.indexOf("application/vnd.ms-excel") > -1)      buffer.append("Excel 文件, ");
        if(accept.indexOf("application/vnd.ms-powerpoint") > -1) buffer.append("PPT 文件, ");
        if(accept.indexOf("application/msword") > -1)            buffer.append("Word 文件, ");
        if(accept.indexOf("text/html") > -1)                     buffer.append("HTML 格式, ");
        if(accept.indexOf("application/xhtml+xml") > -1)         buffer.append("XHTML 格式, ");
        return buffer.replace(buffer.length() - 2, buffer.length() - 1, "").toString();
    }
    //取得 client IP
    private String getRemoteAddr(HttpServletRequest request) {
        String remoteAddr = request.getHeader("x-forwarded-for");
        if (!checkRemoteAddr(remoteAddr)) remoteAddr = request.getHeader("Proxy-Client-IP");
        if (!checkRemoteAddr(remoteAddr)) remoteAddr = request.getHeader("WL-Proxy-Client-IP");
        if (!checkRemoteAddr(remoteAddr)) remoteAddr = request.getHeader("HTTP_CLIENT_IP");
        if (!checkRemoteAddr(remoteAddr)) remoteAddr = request.getHeader("HTTP_X-FORWARDED_FOR");
        if (!checkRemoteAddr(remoteAddr)) remoteAddr = request.getHeader("HTTP_VIA");
        if (!checkRemoteAddr(remoteAddr)) remoteAddr = request.getRemoteAddr(); //Apach有對header再包裝,無法獲取真實IP,所以放最後
        return remoteAddr;
    }
    //檢查 client IP
    private boolean checkRemoteAddr(String remoteAddr) {
        if (remoteAddr == null)                     return false;
        if (remoteAddr.length() == 0)               return false;
        if (remoteAddr.equalsIgnoreCase("null"))    return false;
        if (remoteAddr.equalsIgnoreCase("unknown")) return false;
        return true;
    }
    
    //取得 client OS
    private String getRemoteOS(String userAgent) {
        if(userAgent.indexOf("Windows NT 10.0") > -1)return "Windows 10";
        if(userAgent.indexOf("Windows NT 6.2") > -1) return "Windows 8";
        if(userAgent.indexOf("Windows NT 6.1") > -1) return "Windwos 7";
        if(userAgent.indexOf("Windows NT 6.0") > -1) return "Windows Vista";
        if(userAgent.indexOf("Windows NT 5.1") > -1) return "Windows XP";
        if(userAgent.indexOf("Windows 98") > -1)     return "Windows 98";
        if(userAgent.indexOf("Windows NT 5.0") > -1) return "Windows 2000";
        if(userAgent.indexOf("Android") > -1)        return "Android";
        if(userAgent.indexOf("Max OS") > -1)         return "Mac OS";
        if(userAgent.indexOf("Linux") > -1)          return "Linux";
        if(userAgent.indexOf("Unix") > -1)           return "Unix";
        this.log(userAgent);
        return "未知";
    }
    
    //取得 client 瀏覽器名
    private String getNavigator(String userAgent) {
        if(userAgent.indexOf("Chrome") > -1 )         return "Chrome 瀏覽器";
        if(userAgent.indexOf("TencentTraveler") > -1) return "騰訊瀏覽器";
        if(userAgent.indexOf("Maxthon") > -1)         return "Maxthon 瀏覽器";
        if(userAgent.indexOf("MyIE2") > -1)           return "MyIE2 瀏覽器";
        if(userAgent.indexOf("Firefox") > -1)         return "Firefox 瀏覽器";
        if(userAgent.indexOf("MSIE") > -1)            return "IE 瀏覽器";
        if(userAgent.indexOf("Safari") > -1)          return "Safari 瀏覽器";
        if(userAgent.indexOf("Opera") > -1)           return "Opera 瀏覽器";
        this.log(userAgent);
        return "未知的瀏覽器";
    }
    
    //取得 client 語言環境名稱
    private String getLocale(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 "未知語言環境";
    }
    
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.setCharacterEncoding("UTF-8");
    response.setCharacterEncoding("UTF-8");
    response.setContentType("text/html");

            int localPort = request.getLocalPort();             //本機(Tomcat)Port
    String userAgent = request.getHeader("User-Agent"); //User Agent 訊息,含OS類型及版本、瀏覽器類型及版本等
    String authType = request.getAuthType();            //取得保護servlet的身分驗證名稱(BASIC或SSL),未受保護則回傳null
    StringBuffer requestURL = request.getRequestURL();  //Client 請求之URL
    String remoteAddr = getRemoteAddr(request);         //Client IP
    String remoteOS = getRemoteOS(userAgent);           //Client 作業系統
    String navigator = getNavigator(userAgent);         //Client 瀏覽器
    Locale locale = request.getLocale();                //Client 語言環境
        int remotePort = request.getRemotePort();           //Client Port
        String accept = request.getHeader("Accept");        //Client 瀏覽器支持之格式
        String method = request.getMethod();                //Client 請求方法 GET or POST
        String referer = request.getHeader("referer");      //Client 跳轉頁(從哪個頁面連接到本頁)
        
        String protocol = request.getProtocol();      //Server 協議
String localAddr = request.getLocalAddr();    //Server IP
int serverPort = request.getServerPort();     //Server Port
String localName = request.getLocalName();    //Server 主機名稱
String serverName = request.getServerName();  //Server URL名稱
String requestURI = request.getRequestURI();  //Server 檔案路徑
String servletPath = request.getServletPath();//Server 路徑/檔名
String contextPath = request.getContextPath();//Server context路徑(鄉對路徑)

PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println("  <HEAD><TITLE>Request Servlet</TITLE><HEAD>");
out.println("  <style>body, font, td, div {font-size:12px; line-height:18px;}</style>");
out.println("  <BODY>");

out.println("<b>主機(Tomcat) Port 為 </b>" + localPort + "<br/>");
out.println("<b>User-Agent: </b>" + userAgent + "<br/>");
out.println("<b>Accept: </b>" + accept + "<br/>");
out.println("<b>Servlet受到驗證的方案為 </b>" + authType + "<br/><br/>");

out.println("<b>您請求的網址為 </b>" + requestURL + "<br/>"
          + "<b>您的IP為 </b>" + remoteAddr + "<br/>"
          + "<b>您使用的作業系統為 </b>" + remoteOS + "<br/>"
          + "<b>您使用的瀏覽器為 </b>" + navigator + "<br/>"
          + "<b>您使用的語系為 </b>"+ getLocale(locale) + "<br/>"
                  + "<b>您的瀏覽器使用了</b>" + remotePort + "Port <b>訪問本網頁 </b><br/>"
          + "<b>您的瀏覽器接受 </b>" + getAccept(accept) + "<br/>"
          + "<b>您請求的方法為 </b>" + method + "<br/>"
          + "<b>您從</b> " + referer + " <b>訪問到該頁面 </b></br><br/>");

out.println("<b>Server 協議為 </b> " + protocol + "<br/>"
          + "<b>Server IP為 </b> " + localAddr + "<br/>"
          + "<b>Server Port為 </b>" + serverPort + "<br/>" 
          + "<b>Server 主機名為 </b> " + localName + "<br/>"
          + "<b>Server URL名為</b> " + serverName + "<br/>"
          + "<b>Server 網址路徑為</b> " + requestURI + " <br/>"
          + "<b>Server 目前網頁路徑/檔名為 </b>" + servletPath + "<br/>"
          + "<b>Server 網頁檔案類別名為  </b>" + this.getClass().getName() + "<br/>"
          + "<b>Server 的絕對路徑為 </b>" + this.getServletContext().getRealPath("") + "<br/>"
          + "<b>Server 的相對路徑為 </b>" + contextPath + "<br/><br/>");
out.println("  <a href=" + requestURI + "> 單擊刷新本頁面 </a>");
out.println("  </BODY>");
out.println("</HTML>");
out.flush();
out.close();

//     String queryString = request.getQueryString();                //查詢字串,即?後面的字串
//     String remoteUser = request.getRemoteUser();                  //客戶端用戶
//     String requestedSessionId = request.getRequestedSessionId();  //客戶端 Session ID     
}

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

程式碼上面有附基本的註解,基本上就是介紹 request 方法,如何取得IP、瀏覽器名稱、客戶端及伺服器端的一些值

Accept 的類型還有非常多,眼尖的人可以發現裡面有一個 */* 的符號,也就是代表全部都接受的意思,所以事實上其他都沒甚麼意義,反正全部都可以接受

IP 這就另有學問在,request.getRemoteAddr() 從這取得的沒辦法直接抓到客戶端的 IP,通常是先使用 getHeader("x-forwarded-for") 來抓取,在依程式碼上的依序往下抓
呈現畫面上看到 0:0:0:0:0:0:0:1 或 127.0.0.1 是正常的,因為我是在本機跑此網頁,所以跟 Server IP 是一樣的

User-Agent 仔細看就可以看到包含 OS、瀏覽器等名稱

其他很多可以參考上述程式碼,寫得很簡單應該滿好理解的
有問題歡迎留言一起討論~



留言

這個網誌中的熱門文章

[面試] 日月光 設備工程師

[日文] Google日文輸入法 簡單安裝說明

[Windows] 還我 win7 相片檢視器!!