适配器模式应用~获取IP地址时想起了适配器

news/2024/12/18 13:51:24/文章来源:https://www.cnblogs.com/lori/p/18614743

获取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;}@Overridepublic String getHeader(String name) {return request.getHeader(name);}@Overridepublic String getRemoteAddr() {return request.getRemoteAddr();}}

NettyRequestFacade的包装

public class NettyRequestWrapper implements RequestWrapper {private final NettyRequestFacade request;public NettyRequestWrapper(NettyRequestFacade request) {this.request = request;}@Overridepublic String getHeader(String name) {return request.getHeader(name);}@Overridepublic 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")) {// 根据网卡取本机配置的IPInetAddress 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));
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/854782.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

window终止占用某个端口的进程

1.查看当前端口 netstat -ano | findstr 端口号 2.终结占用当前端口的服务 taskkill /PID 进程号 /T /F

ABB喷涂机器人ACU 3HNA024871-001维修

ABB喷涂机器人ACU 3HNA024871-001在以下情况下可能会出现气压异常: - 气压要求变化:如果气压要求从8巴降至6巴,这可能会导致气压异常。 - 设备故障:如果ACU设备本身出现故障,例如内部压降问题或者闭环调节系统出现问题,也可能导致气压异常。 - 维护不当:如…

Z-BlogPHP 报错“error-9 该文章不存在或设置了权限”,如何解决?

当您在使用 Z-BlogPHP 时遇到“error-9 该文章不存在或设置了权限”的错误,通常是因为文章的状态被更改或设置了访问权限。以下是一些解决此问题的方法:检查文章状态:确认文章的状态是否为已发布。如果文章被设置为草稿或其他未发布的状态,非作者或管理员账号将无法访问。 …

Z-BlogPHP 报错“主题模板的编译文件不存在”,如何解决?

当您在使用 Z-BlogPHP 时遇到“主题模板的编译文件不存在”的错误,通常是因为系统未能正确编译主题模板文件,导致无法正常显示网站内容。以下是一些解决此问题的方法:清空缓存并重新编译模板:登录 Z-BlogPHP 后台管理界面,进入首页。 在首页中,找到并点击“清空缓存并重新…

UniApp小程序开发避坑事项

首次使用UniApp及其UI进行小程序开发,记录项目中需要注意事项,方便以后避坑^_^! 1、uni-forms的使用,如果需要自定义校验,uni-forms上不能绑定rules,需要在data中定义rules,然后在onReady中将uni-forms与rules绑定。<uni-forms ref="valiForm" :modelValue=…

探索全新摸鱼世界,【摸鱼办】一站式轻松解决打工人在线摸鱼的秘密武器!

你好,摸鱼人!👨‍💻 工作再忙,一定不要忘记摸鱼哦 🐟! 有事没事起身去茶水间 ☕️,去厕所 🚾,去走廊走走 🚶,去找同事聊聊八卦 🆕!别老在工位上坐着,钱是老板的 👨‍💼 但命是自己的 🤷‍♂️。00. 什么是【摸鱼办】? 摸鱼办是一款专为上班族打造的…

C10-8 SQL注入II + XSS练习 I

情境参加了培训的第八次课, 涉及到了SQL宽字节注入, 从MySQL注入到GetShell, SQL注入的基本绕过手法, SQL注入防御, SQLmap的使用; XSS基本概念和原理 的介绍(包括3种XSS及其手动测试). 这里是第八课的作业题, 及我的解答. (注: 使用本地虚拟机开启dvwa靶场, 10.0.0.155是ubunt…

【流量分析】基于安全产品DNS隧道流量分析

免责声明 本文仅限于技术讨论与分享,严禁用于非法途径。若读者因此作出任何危害网络安全行为后果自负,与本号及原作者无关。域名准备 选择哪家的云都没问题,这里我选择的TX云,因为之前注册过了,自己拿来做个流量分析不成问题。 域名添加解析记录 需要准备自己的vps作为DNS…

14伪元素-CSS的继承和层叠-元素特性

一、之前剩下的东西 上节讲解了CSS常见的选择器:通用选择器,元素选择器,类选择器,id选择器,属性选择器,组合选择器,伪类选择器 之前讲到伪类选择器非常多,但是使用的却不多,上次主要讲到动态伪类,其中:hover最重要。 1、伪元素pseudo-elements 常用的伪元素是: :fir…

分享一个线程状态

本文来自博客园,作者:Eular,转载请注明原文链接:https://www.cnblogs.com/euler-blog/p/18614627

Bootstrap popover功能扩展jquery插件

这是一款Bootstrap popover功能扩展jquery插件。该jquery插件在原生Bootstrap popover功能的基础上,添加了一些新的功能,例如自动定位,支持情景模式等。在线演示 下载使用方法 在页面中引入jquery和bootstrap相关文件,以及bootstrap-popover-x.css和bootstrap-popover-x.j…

大学微积分 AB 第四单元:区分的语境应用

(先略)根据上下文解释导数的含义 定的。