找回密码
 立即注册
首页 业界区 业界 适配器模式应用~获取IP地址时想起了适配器 ...

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

官厌 2025-6-6 14:11:42
获取IP地址信息时,一般我们需要一个HttpServletRequest对象,然后从请求头里获取x-forwarded-for的值,而当我们使用dubbo+netty开发rest接口时,如果希望获取IP地址,HttpServletRequest是用不了的,你需要使用netty中的NettyRequestFacade对象,这时,你之前的获取IP地址的方法需要扩展,加一个只有入参不一样,代码逻辑完成一样的丑陋的,重复的代码;这无疑是一种代码的坏味道,应该想办法解决它。
适配器(包装器)

这种常用的设计模式在spring框架里用的非常多,如ServletRequestAttributes,它包装了HttpServletRequest和HttpServletResponse,用来添加额外的功能,如获取请求参数、session等信息。
为获取IP地址添加包装

自己的http请求包装器接口RequestWrapper
  1. public interface RequestWrapper {
  2.         String getHeader(String name);
  3.         String getRemoteAddr();
  4. }
复制代码
HttpServletRequest的包装
  1. public class HttpRequestWrapper implements RequestWrapper {
  2.         private final HttpServletRequest request;
  3.         public HttpRequestWrapper(HttpServletRequest request) {
  4.                 this.request = request;
  5.         }
  6.         @Override
  7.         public String getHeader(String name) {
  8.                 return request.getHeader(name);
  9.         }
  10.         @Override
  11.         public String getRemoteAddr() {
  12.                 return request.getRemoteAddr();
  13.         }
  14. }
复制代码
NettyRequestFacade的包装
  1. public class NettyRequestWrapper implements RequestWrapper {
  2.         private final NettyRequestFacade request;
  3.         public NettyRequestWrapper(NettyRequestFacade request) {
  4.                 this.request = request;
  5.         }
  6.         @Override
  7.         public String getHeader(String name) {
  8.                 return request.getHeader(name);
  9.         }
  10.         @Override
  11.         public String getRemoteAddr() {
  12.                 return request.getRemoteAddr();
  13.         }
  14. }
复制代码
获取IP地址方法,入参是一个http包装器
  1. public static String getIpAddr(RequestWrapper request) {
  2.                 String ip = request.getHeader("x-forwarded-for");
  3.                 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  4.                         ip = request.getHeader("Proxy-Client-IP");
  5.                 }
  6.                 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  7.                         ip = request.getHeader("WL-Proxy-Client-IP");
  8.                 }
  9.                 if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
  10.                         ip = request.getRemoteAddr();
  11.                         if (ip.equals("127.0.0.1")) {
  12.                                 // 根据网卡取本机配置的IP
  13.                                 InetAddress inet = null;
  14.                                 try {
  15.                                         inet = InetAddress.getLocalHost();
  16.                                 }
  17.                                 catch (UnknownHostException e) {
  18.                                         e.printStackTrace();
  19.                                 }
  20.                                 ip = inet != null ? inet.getHostAddress() : ip;
  21.                         }
  22.                 }
  23.                 // 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
  24.                 if (ip != null && ip.length() > 15) {
  25.                         if (ip.indexOf(",") > 0) {
  26.                                 ip = ip.substring(0, ip.indexOf(","));
  27.                         }
  28.                 }
  29.                 if ("0:0:0:0:0:0:0:1".equals(ip)) {
  30.                         ip = "127.0.0.1";
  31.                 }
  32.                 return ip;
  33.         }
复制代码
调用示例:
  1. // 使用HttpServletRequest
  2. public String getIpFromHttp(HttpServletRequest request) {
  3.     return getIpAddr(new HttpRequestWrapper(request));
  4. }
  5. // 使用NettyRequestFacade
  6. public String getIpFromNetty(NettyRequestFacade request) {
  7.     return getIpAddr(new NettyRequestWrapper(request));
  8. }
复制代码
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册