I get some user data through a simple form. When dealing with the data in the corresponding backing bean's action method, I am currently getting the IP address of a user this way:
HttpServletRequest request = (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
String ipAddress = request.getHeader( "X-FORWARDED-FOR" );
if ( ipAddress == null ) {
ipAddress = request.getRemoteAddr();
}
Is there another way, a more "JSF" way, where I wouldn't need to hook on HttpServletRequest
? I read many times that having to use javax.servlet.*
in a @ManagedBean
is not a good design, but I couldn't find anything else.
No, there isn't. The ExternalContext
doesn't have a method which delegates to ServletRequest#getRemoteAddr()
.
Your best bet is to hide it away in an utlity method. The JSF utility library OmniFaces has among many other helpful methods exactly this method in the Faces
utility class: Faces#getRemoteAddr()
which also takes forwarded address into account.
The source code is here:
/**
* 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();
}
Note that X-Forwarded-For
header represents a commaseparated string and that your own code didn't take that into account.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With