Saya sedang mengerjakan proyek pengontrol MVC Spring di mana saya membuat panggilan GET URL dari browser -
Di bawah ini adalah url yang saya gunakan untuk melakukan panggilan GET dari browser -
http://127.0.0.1:8080/testweb/processing?workflow=test&conf=20140324&dc=all
Dan di bawah ini adalah kode di mana panggilan muncul setelah masuk ke browser -
@RequestMapping(value = "processing", method = RequestMethod.GET)
public @ResponseBody ProcessResponse processData(@RequestParam("workflow") final String workflow,
@RequestParam("conf") final String value, @RequestParam("dc") final String dc) {
System.out.println(workflow);
System.out.println(value);
System.out.println(dc);
// some other code
}
Pernyataan masalah:-
Sekarang adakah cara, saya dapat mengekstrak Alamat IP dari beberapa header? Artinya saya ingin tahu dari alamat IP mana, panggilan datang, artinya siapa pun yang menelepon di atas URL, saya perlu tahu alamat IP mereka. Apakah ini mungkin untuk dilakukan?
java
spring-mvc
ip-address
john
sumber
sumber
Jawaban:
Solusinya adalah
@RequestMapping(value = "processing", method = RequestMethod.GET) public @ResponseBody ProcessResponse processData(@RequestParam("workflow") final String workflow, @RequestParam("conf") final String value, @RequestParam("dc") final String dc, HttpServletRequest request) { System.out.println(workflow); System.out.println(value); System.out.println(dc); System.out.println(request.getRemoteAddr()); // some other code }
Tambahkan
HttpServletRequest request
ke definisi metode Anda dan kemudian gunakan Servlet APIDokumentasi Musim Semi di sini tertulis
Handler methods that are annotated with @RequestMapping can have very flexible signatures. Most of them can be used in arbitrary order (see below for more details). Request or response objects (Servlet API). Choose any specific request or response type, for example ServletRequest or HttpServletRequest
sumber
Saya terlambat di sini, tetapi ini mungkin membantu seseorang mencari jawabannya. Biasanya
servletRequest.getRemoteAddr()
bekerja.Dalam banyak kasus, pengguna aplikasi Anda mungkin mengakses server web Anda melalui server proxy atau mungkin aplikasi Anda berada di belakang penyeimbang beban.
Jadi Anda harus mengakses header http X-Forwarded-For dalam kasus seperti itu untuk mendapatkan alamat IP pengguna.
misalnya
String ipAddress = request.getHeader("X-FORWARDED-FOR");
Semoga ini membantu.
sumber
X-Forwarded-For
biasanya daftar ips dipisahkan dengan koma, dengan setiap proxy dalam rangkaian menambahkan alamat jarak jauh yang dilihatnya ke daftar. Jadi, implementasi yang baik biasanya memiliki daftar proxy tepercaya dan "lewati" ip tersebut saat membaca header ini dari kanan ke kiri.Saya menggunakan metode seperti itu untuk melakukan ini
public class HttpReqRespUtils { private static final String[] IP_HEADER_CANDIDATES = { "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_CLIENT_IP", "HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_VIA", "REMOTE_ADDR" }; public static String getClientIpAddressIfServletRequestExist() { if (RequestContextHolder.getRequestAttributes() == null) { return "0.0.0.0"; } HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); for (String header: IP_HEADER_CANDIDATES) { String ipList = request.getHeader(header); if (ipList != null && ipList.length() != 0 && !"unknown".equalsIgnoreCase(ipList)) { String ip = ipList.split(",")[0]; return ip; } } return request.getRemoteAddr(); } }
sumber
Anda bisa mendapatkan alamat IP secara statis dari
RequestContextHolder
seperti di bawah ini:sumber
Letakkan metode ini di BaseController Anda:
@SuppressWarnings("ConstantConditions") protected String fetchClientIpAddr() { HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.getRequestAttributes())).getRequest(); String ip = Optional.ofNullable(request.getHeader("X-FORWARDED-FOR")).orElse(request.getRemoteAddr()); if (ip.equals("0:0:0:0:0:0:0:1")) ip = "127.0.0.1"; Assert.isTrue(ip.chars().filter($ -> $ == '.').count() == 3, "Illegal IP: " + ip); return ip; }
sumber
Lihat di bawah. Kode ini bekerja dengan spring-boot dan spring-boot + apache CXF / SOAP.
// in your class RequestUtil private static final String[] IP_HEADER_NAMES = { "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_CLIENT_IP", "HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_VIA", "REMOTE_ADDR" }; public static String getRemoteIP(RequestAttributes requestAttributes) { if (requestAttributes == null) { return "0.0.0.0"; } HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); String ip = Arrays.asList(IP_HEADER_NAMES) .stream() .map(request::getHeader) .filter(h -> h != null && h.length() != 0 && !"unknown".equalsIgnoreCase(h)) .map(h -> h.split(",")[0]) .reduce("", (h1, h2) -> h1 + ":" + h2); return ip + request.getRemoteAddr(); } //... in service class: String remoteAddress = RequestUtil.getRemoteIP(RequestContextHolder.currentRequestAttributes());
:)
sumber
Di bawah ini adalah cara Spring, dengan
autowired
request bean di@Controller
kelas:@Autowired private HttpServletRequest request; System.out.println(request.getRemoteHost());
sumber
@Controller
contoh menggunakan@Autowired
. Jika tidak, Anda harus menggunakan@Scope(BeanDefinition.SCOPE_PROTOTYPE)
kelas pengontrol untuk memastikan bahwa instance baru pengontrol dibuat dengan setiap permintaan. Ini kurang efisien, tetapi merupakan solusi jika Anda harus memasukkan sesuatu sebagai properti ke kelas kontroler.Dalam kasus saya, saya menggunakan Nginx di depan aplikasi saya dengan konfigurasi berikut:
location / { proxy_pass http://localhost:8080/; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; add_header Content-Security-Policy 'upgrade-insecure-requests'; }
jadi dalam aplikasi saya, saya mendapatkan ip pengguna yang sebenarnya seperti:
String clientIP = request.getHeader("X-Real-IP");
sumber
private static final String[] IP_HEADER_CANDIDATES = { "X-Forwarded-For", "Proxy-Client-IP", "WL-Proxy-Client-IP", "HTTP_X_FORWARDED_FOR", "HTTP_X_FORWARDED", "HTTP_X_CLUSTER_CLIENT_IP", "HTTP_CLIENT_IP", "HTTP_FORWARDED_FOR", "HTTP_FORWARDED", "HTTP_VIA", "REMOTE_ADDR" }; public static String getIPFromRequest(HttpServletRequest request) { String ip = null; if (request == null) { if (RequestContextHolder.getRequestAttributes() == null) { return null; } request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); } try { ip = InetAddress.getLocalHost().getHostAddress(); } catch (Exception e) { e.printStackTrace(); } if (!StringUtils.isEmpty(ip)) return ip; for (String header : IP_HEADER_CANDIDATES) { String ipList = request.getHeader(header); if (ipList != null && ipList.length() != 0 && !"unknown".equalsIgnoreCase(ipList)) { return ipList.split(",")[0]; } } return request.getRemoteAddr(); }
Saya menggabungkan kode di atas ke kode ini berfungsi untuk banyak kasus. Teruskan yang
HttpServletRequest request
Anda dapatkan dari api ke metodesumber