论坛首页 Java企业应用论坛

Rop开源框架重大升级周知(10多个新功能给力开发!!)

浏览 8081 次
精华帖 (7) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-06-13  
melin 写道
ServletRequestContextBuilder 中获取IP方法 request.getRemoteAddr();
在有代理的情况下,获取不到真实的IP。


public static String getRemoteIP(HttpServletRequest request) {
    String remoteIP = request.getHeader("X-Real-IP");
if (!StringUtils.hasText(remoteIP)) {
remoteIP = request.getRemoteAddr();
}
return remoteIP;
}


谢谢,我马上改下,看了另外一位兄弟的帖子更全些http://ytfei.iteye.com/blog/811868
引用
服务器上运行nginx 转发请求到 tomcat 8080 的jsp
获取到的信息

request.getHeader("x-real-ip");= 58.x.x.x
request.getHeader("x-forwarded-for");=10.15.x.x, 58.x.x.x
request.getHeader("Proxy-Client-IP");=null
request.getHeader("WL-Proxy-Client-IP");=null
request.getRemoteAddr();=202.x.x.x

直接访问 tomcat 8080 的jsp

request.getHeader("x-real-ip");= null
request.getHeader("x-forwarded-for");=10.15.x.x
request.getHeader("Proxy-Client-IP");=null
request.getHeader("WL-Proxy-Client-IP");=null
request.getRemoteAddr();=58.x.x.x

客户端浏览器是有用代理的 58.x.x.x 是代理的公网IP。10.15.x.x 是客户端的局域网IP。 202.x.x.x 是tomcat服务器的IP

因此如果想获取远程用户上网的IP,只要获取 x-real-ip 如果 x-real-ip 为空,直接获取  request.getRemoteAddr();


如果使用apache反向代理则参见http://www.blogjava.net/kingmove/articles/266606.html
引用

apache反向代理,如何获取用户真实IP
很多时候项目都需要获取用户的真实IP进行一些分析或者权限过滤,一般情况下通过request.getRemoteAddr()就可取得客户端的IP地址,但是在通过了Apache,Squid等反向代理软件就不能获取到客户端的真实IP地址了。

如果使用了反向代理软件,将http://192.168.1.110:2046/ 的URL反向代理为http://www.xxx.com/ 的URL时,用request.getRemoteAddr()方法获取的IP地址是:127.0.0.1 或 192.168.1.110,而并不是客户端的真实IP。

经过代理以后,由于在客户端和服务之间增加了中间层,因此服务器无法直接拿到客户端的IP,服务器端应用也无法直接通过转发请求的地址返回给客户端。但是在转发请求的HTTP头信息中,增加了X-FORWARDED-FOR信息用以跟踪原有的客户端IP地址和原来客户端请求的服务器地址。
原来如此,我们的项目中正好是有前置apache,将一些请求转发给后端的weblogic,看来就是这样导致的咯。

给出一份还算靠谱的代码,如下:



Java代码
  public String getIpAddr(HttpServletRequest 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(); 
     } 
     return ip; 

如果有人遇到类似问题,请多加留意,呵呵。



PS:可是,如果通过了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串Ip值,究竟哪个才是真正的用户端的真实IP呢?
答案是取X-Forwarded-For中第一个非unknown的有效IP字符串。如:X-Forwarded-For:192.168.1.110, 192.168.1.120, 192.168.1.130, 192.168.1.100,用户真实IP为: 192.168.1.110
0 请登录后投票
   发表时间:2012-06-13   最后修改:2012-06-13
现在开源出来的代码感觉有问题
没有地方调用DefaultRopContext  public void addServiceMethod(String methodName, String version, ServiceMethodHandler serviceMethodHandler) {方法,

应该用BeanPostProcessor类? 开源的代码中没有
0 请登录后投票
   发表时间:2012-06-13  
melin 写道
现在开源出来的代码感觉有问题
没有地方调用DefaultRopContext  public void addServiceMethod(String methodName, String version, ServiceMethodHandler serviceMethodHandler) {方法,

应该用BeanPostProcessor类? 开源的代码中没有


有啊,DefaultRopContext本身的registerFromContext()方法就调用这个方法进行处理方法注册的,这个方法还允许你动态在运行期注册一个服务方法。
0 请登录后投票
   发表时间:2012-06-13  
stamen 写道
melin 写道
现在开源出来的代码感觉有问题
没有地方调用DefaultRopContext  public void addServiceMethod(String methodName, String version, ServiceMethodHandler serviceMethodHandler) {方法,

应该用BeanPostProcessor类? 开源的代码中没有


有啊,DefaultRopContext本身的registerFromContext()方法就调用这个方法进行处理方法注册的,这个方法还允许你动态在运行期注册一个服务方法。

哦,sorry!
0 请登录后投票
   发表时间:2012-06-13  
melin 写道
ServletRequestContextBuilder 中获取IP方法 request.getRemoteAddr();
在有代理的情况下,获取不到真实的IP。


public static String getRemoteIP(HttpServletRequest request) {
    String remoteIP = request.getHeader("X-Real-IP");
if (!StringUtils.hasText(remoteIP)) {
remoteIP = request.getRemoteAddr();
}
return remoteIP;
}


我已经更改了,参照你的实现,我的实现版本是:
    private String getRemoteAddr(HttpServletRequest request) {
        String remoteIp = request.getHeader(X_REAL_IP); //nginx反向代理
        if (StringUtils.hasText(remoteIp)) {
            return remoteIp;
        } else {
            remoteIp = request.getHeader(X_FORWARDED_FOR);//apache反射代理
            if (StringUtils.hasText(remoteIp)) {
                String[] ips = remoteIp.split(",");
                for (String ip : ips) {
                    if (!"null".equalsIgnoreCase(ip)) {
                        return ip;
                    }
                }
            }
            return request.getRemoteAddr();
        }
    }


添加了代理是apache的情况,代码已经提交 Commit 信息:
引用

   fix the bug of get Remoate client ip from the nigix or apache proxy the backend server(thanks for     melin[bsli@xxx.com.cn]).
0 请登录后投票
   发表时间:2012-06-14  
lz,UserRestService服务类应该会直接调用业务逻辑接口来完成具体的业务请求吧?
目前demo都是直接返回一个response
0 请登录后投票
   发表时间:2012-06-14  
kelloKitty 写道
lz,UserRestService服务类应该会直接调用业务逻辑接口来完成具体的业务请求吧?
目前demo都是直接返回一个response


可以直接在UserRestService中完成业务,也可以调用其它Service,这看你自己设计了(一般是调用其它的Service)
0 请登录后投票
   发表时间:2012-06-14  
学习了啊,用起来挺方便的
0 请登录后投票
   发表时间:2012-06-14  
melin兄昨天给我提交了一份代码(发短信给我),是关于Rop会话实现的,我今天看了一下,感觉实现得非常好,我会尽快将其整合到Rop中,也欢迎大家贡献Rop的代码,一起把这个开源软件做好做强!

大家可以将代码更改 或新的功能 通过站内短信,或发邮件给我,我的邮箱是:itstamen@qq.com

欢迎加入Rop群组:http://rop.group.iteye.com/ 现开放加入,不用审核。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics