获取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));
- }
复制代码 来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |