适配器模式应用~获取IP地址时想起了适配器
获取IP地址信息时,一般我们需要一个HttpServletRequest对象,然后从请求头里获取x-forwarded-for的值,而当我们使用dubbo+netty开发rest接口时,如果希望获取IP地址,HttpServletRequest是用不了的,你需要使用netty中的NettyRequestFacade对象,这时,你之前的获取IP地址的方法需要扩展,加一个只有入参不一样,代码逻辑完成一样的丑陋的,重复的代码;这无疑是一种代码的坏味道,应该想办法解决它。
适配器(包装器)
这种常用的设计模式在spring框架里用的非常多,如ServletRequestAttributes,它包装了HttpServletRequest和HttpServletResponse,用来添加额外的功能,如获取请求参数、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地址方法,入参是一个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")) {
// 根据网卡取本机配置的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;
}
调用示例:
// 使用HttpServletRequest
public String getIpFromHttp(HttpServletRequest request) {
return getIpAddr(new HttpRequestWrapper(request));
}
// 使用NettyRequestFacade
public String getIpFromNetty(NettyRequestFacade request) {
return getIpAddr(new NettyRequestWrapper(request));
}
适配器模式应用~获取IP地址时想起了适配器的更多相关文章
- 解决获取IP地址时出现“在一个非套…
今天单位的一台机器在用IPCONFIG/RENEW时遇到了这个问题,上网查了一下,网上的版本在对XP不太好用,网上的版本如下: 1.从注册表中备份以下项:(当然也可以用Erunt备份整个注册表)HKE ...
- ubuntu16.04无法获取ip地址的解决方案
当我们无法获取ip地址时可以使用dhcp来动态获取ip地址,安装dhcpcd5和dhcpcd-gtk sudo apt-get install dhcpcd5 sudo apt-get install ...
- DHCP获取IP地址过程中捕获的报文—三级网络总结(二)
上一篇文章主要说了一下知识点中的IP地址的考点,这一篇我打算说说DHCP获取IP地址过程中捕获的报文的这个考点,都是自己的理解,有错误欢迎指正. DHCP是应用层协议,UDP是传输层协议,IP是网络层 ...
- vc根据域名获取IP地址 gethostbyname()函数
以下是VC Socket初始化时用到的两个函数 一.WSAStartup函数 int WSAStartup ( ...
- iOS根据域名获取ip地址
引入头文件 #include <netdb.h> #include <sys/socket.h> #include <arpa/inet.h> //根据域名获取ip ...
- linux如何自动获取ip地址
第一步:激活网卡 系统装好后默认的网卡是eth0,用下面的命令将这块网卡激活. # ifconfig eth0 up 第二步:设置网卡进入系统时启动 想要每次开机就可以自动获取IP地址上网,就要设置网 ...
- 1. 通过DHCP服务器动态获取IP地址之后无法上网的解决方法
故障:内网正常,在同一个局域网内的其它PC端通过DHCP获取IP地址并且可以正常上网. 1.通过wireshark抓包,使用ipconfig /renew时,wireshark内出现DHCP请求服务, ...
- php 获取ip地址的5种方法,插入用户登录日志实例
php 获取ip地址的5种方法,插入用户登录日志实例,推荐使用第二种方法 <?php //方法1: $ip = $_SERVER["REMOTE_ADDR"]; echo $ ...
- PHP 获取IP地址位置信息「聚合数据API」
聚合数据 提供了[查询IP所属区域]的服务接口,只需要以 GET 请求的方式向 API 传入 IP地址 和 APPKEY 即可获得查询结果. 这里的难点主要在于如何通过PHP获取客户端IP地址,以及如 ...
- JavaScript和微信小程序获取IP地址的方法
最近公司新加了一个需求,根据用户登录的IP地址判断是否重复登录,重复登录就进行逼退,那么怎么获取到浏览器的IP地址呢?最后发现搜狐提供了一个JS接口,可以通过它获取到客户端的IP. 接口地址如下: h ...
随机推荐
- [OI] 珂朵莉树
对于一个序列,它有较多重复元素,并且题目需要维护区间修改,维护区间信息,维护整块值域信息的,那么就可以考虑珂朵莉树解决. 主要思想 珂朵莉树将全部相同的颜色块压缩为一组,如对于下述序列: 1 1 1 ...
- 创建一个简单的基于MyBatis的项目
- linux命令杂记
chmod 777 lixiangj 修改目录为共享权限cd .. 跳转上一级目录cd - 跳转上一次跳转的目录ll 查看目录下所有文件ctrl+L 清除屏幕内容| head -10 只看结果中的前1 ...
- KubeSphere Cloud 月刊|灾备支持 K8s 1.22+,轻量集群支持安装灾备和巡检组件
功能升级 备份容灾服务支持 K8s v1.22+ 版本集群 随着 Kubernetes 近一年频繁的发版.升级,越来越多的用户开始部署并使用高版本的 Kubernetes 集群.备份容灾服务支持 Ku ...
- Ubuntu 22.04 解决和 Windows 共享蓝牙设备的问题
我有一个 Airpods,连接到 WIndows 可以正常工作,但连接到 ubuntu 后会无法连接,只能删除设备选择重联,但是这又会导致 Windows 不能连接到耳机,只能也删除重新连接,费神费力 ...
- synchronized的四种锁状态
Java 多线程的锁都是基于对象的,Java 中的每一个对象都可以作为一个锁. 类锁,其实就是 Class 对象的锁. Class 对象是一种特殊的 Java 对象,代表了程序中的类和接口.Java ...
- python操作pptx设置title字体大小插入全屏图片A4尺寸实例一枚
pip install python-pptx 安装好pptx,设置标题最大的作用是ppt里面的摘要视图显示摘要文字 参考:https://python-pptx.readthedocs.io/en/ ...
- Next.js 与 React 全栈开发:整合 TypeScript、Redux 和 Ant Design
在上一集,我们编写完毕导航页面,并且非常的美观,但是我们发现编写网站是存静态的,在现代的网站当中一般都是动静结合,也就是说部分数据是从数据库读取的,部分静态数据是写在网页上面的,因此这章讲述如何搭建一 ...
- visual studio当中动态库和静态库的联系
一.为什么要写这篇博客 公司需要调用MNN框架编译之后的动态库和静态库文件来在另外一台没有编译过MNN框架上的机器运行对应的程序,比如说人体关键点检测之类的程序,这个时候了解静态库和动态库的关系就很有 ...
- clone:克隆数据,可深度克隆
这里列出了原始类型,时间.正则.错误.数组.对象的克隆规则,其他的可自行补充 function clone(value, deep){ if(isPrimitive(value)){ return v ...