適配器模式應用~獲取IP地址時想起了適配器
獲取IP地址信息時,一般我們需要一個HttpServletRequest對象,然后從請求頭里獲取x-forwarded-for的值,而當我們使用dubbo+netty開發(fā)rest接口時,如果希望獲取IP地址,HttpServletRequest是用不了的,你需要使用netty中的NettyRequestFacade對象,這時,你之前的獲取IP地址的方法需要擴展,加一個只有入?yún)⒉灰粯樱a邏輯完成一樣的丑陋的,重復的代碼;這無疑是一種代碼的壞味道,應該想辦法解決它。
適配器(包裝器)
這種常用的設計模式在spring框架里用的非常多,如ServletRequestAttributes,它包裝了HttpServletRequest和HttpServletResponse,用來添加額外的功能,如獲取請求參數(shù)、session等信息。
為獲取IP地址添加包裝
自己的http請求包裝器接口RequestWrapper
public interface RequestWrapper {
String getHeader(String name);
String getRemoteAddr();
}
HttpServletRequest的包裝
public class HttpRequestWrapper implements RequestWrapper {
private final HttpServletRequest request;
public HttpRequestWrapper(HttpServletRequest request) {
this.request = request;
}
@Override
public String getHeader(String name) {
return request.getHeader(name);
}
@Override
public String getRemoteAddr() {
return request.getRemoteAddr();
}
}
NettyRequestFacade的包裝
public class NettyRequestWrapper implements RequestWrapper {
private final NettyRequestFacade request;
public NettyRequestWrapper(NettyRequestFacade request) {
this.request = request;
}
@Override
public String getHeader(String name) {
return request.getHeader(name);
}
@Override
public String getRemoteAddr() {
return request.getRemoteAddr();
}
}
獲取IP地址方法,入?yún)⑹且粋€http包裝器
public static String getIpAddr(RequestWrapper 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();
if (ip.equals("127.0.0.1")) {
// 根據(jù)網(wǎng)卡取本機配置的IP
InetAddress inet = null;
try {
inet = InetAddress.getLocalHost();
}
catch (UnknownHostException e) {
e.printStackTrace();
}
ip = inet != null ? inet.getHostAddress() : ip;
}
}
// 對于通過多個代理的情況,第一個IP為客戶端真實IP,多個IP按照','分割
if (ip != null && ip.length() > 15) {
if (ip.indexOf(",") > 0) {
ip = ip.substring(0, ip.indexOf(","));
}
}
if ("0:0:0:0:0:0:0:1".equals(ip)) {
ip = "127.0.0.1";
}
return ip;
}
調(diào)用示例:
// 使用HttpServletRequest
public String getIpFromHttp(HttpServletRequest request) {
return getIpAddr(new HttpRequestWrapper(request));
}
// 使用NettyRequestFacade
public String getIpFromNetty(NettyRequestFacade request) {
return getIpAddr(new NettyRequestWrapper(request));
}
浙公網(wǎng)安備 33010602011771號