4

我通过一个简单的表格获得了一些用户数据。在处理相应 backing bean 的 action 方法中的数据时,我目前正在通过这种方式获取用户的 IP 地址:

HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
String ipAddress = request.getHeader( "X-FORWARDED-FOR" );
if ( ipAddress == null ) {
    ipAddress = request.getRemoteAddr();
}

还有另一种方式,一种更“JSF”的方式,我不需要挂钩HttpServletRequest吗?我读了很多次,不得不javax.servlet.*在 a@ManagedBean中使用不是一个好的设计,但我找不到其他任何东西。

4

1 回答 1

16

不,没有。ExternalContext没有委托ServletRequest#getRemoteAddr()给.

最好的办法是用实用方法将其隐藏起来。JSF 实用程序库OmniFaces在实用程序类中有许多其他有用的方法,正是这种方法FacesFaces#getRemoteAddr()它还考虑了转发地址。

源代码在这里:

/**
 * Returns the Internet Protocol (IP) address of the client that sent the request. This will first check the
 * <code>X-Forwarded-For</code> request header and if it's present, then return its first IP address, else just
 * return {@link HttpServletRequest#getRemoteAddr()} unmodified.
 * @return The IP address of the client.
 * @see HttpServletRequest#getRemoteAddr()
 * @since 1.2
 */
public static String getRemoteAddr() {
    String forwardedFor = getRequestHeader("X-Forwarded-For");

    if (!Utils.isEmpty(forwardedFor)) {
        return forwardedFor.split("\\s*,\\s*", 2)[0]; // It's a comma separated string: client,proxy1,proxy2,...
    }

    return getRequest().getRemoteAddr();
}

请注意,X-Forwarded-For标头代表一个逗号分隔的字符串,您自己的代码没有考虑到这一点。

于 2013-03-28T10:46:11.810 回答