-Dcatalina.base="D:\workspace\28.CitizenService\.metadata\.plugins\org.eclipse.wst.server.core\tmp0" -Dcatalina.home="D:\developSet\apache-tomcat-7.0.77-windows-x64\apache-tomcat-7.0.77" -Dwtp.deploy="D:\workspace\28.CitizenService\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps" -Djava.endorsed.dirs="D:\developSet\apache-tomcat-7.0.77-windows-x64\apache-tomcat-7.0.77\endorsed"
-Djava.net.preferIPv4Stack=true
[Controller.java]
/**
* ip중복 제외하여 조회수 카운트
* @param searchVO
* @param request
* @throws Exception
*/
@RequestMapping(value="/board/boardReadCnt.do")
public void boardReadCnt(@ModelAttribute("searchVO") BoardVO searchVO, HttpServletRequest request) throws Exception {
/*ip찾는 로직*/
String ip = request.getHeader("X-Forwarded-For");
if (ip == null) {
ip = request.getRemoteAddr();
}
searchVO.setClientIp(ip);
searchVO.setBoardId(searchVO.getBoardId());
//clientIpCnt 리턴 형태: select == 0 처음 클릭된 / select !== 0 처음으로 클릭된게 아닌
int clientIpCnt = boardService.selectClientIpCnt(searchVO);
if(clientIpCnt == 0){
//CLIENT_CHECK 테이블에 IP와 BOARD_ID 입력
boardService.insertClientIp(searchVO);
//BOARD 테이블에 READ_CNT 카운트 1 업데이트
boardService.updateBoardReadCnt(searchVO);
}
}
[Board_SQL.xml]
<update id="boardDAO.updateBoardReadCnt">
UPDATE BOARD
SET READ_CNT = IFNULL(READ_CNT, 0) + 1
WHERE 1=1
AND BOARD_ID = #boardId#
LIMIT 1
</update>
<insert id="boardDAO.insertClientIp" parameterClass="boardVO">
INSERT INTO CLIENT_CHECK
( BOARD_ID,
CLIENT_IP
) VALUES (
#boardId#,
#clientIp#
)
</insert>
<select id="boardDAO.selectClientIpCnt" resultClass="Integer">
SELECT COUNT(CC.CLIENT_IP) AS CLIENT_IP_CNT
FROM CLIENT_CHECK CC
WHERE CC.CLIENT_IP = #clientIp#
AND CC.BOARD_ID = #boardId#
</select>
request.getRemoteAddr(); 이 메소드로 client ip를 가져올 수 있다.
1. 아이피를 쌓아둔 테이블에서 현재 조회한 ip가 있는지 select 한 후 count 형태로 리턴한다.
2. 현재아이피가 테이블 데이터에 있으면 이미 한번 확인을 했던 아이피라서 1을 리턴한다.
3. 0을 리턴했을경우 현재 조회된 아이피를 insert하고 조회수 칼럼의 데이터도 update를 한다.
혹여 ip가 ipv4 형태(0:0:0:0:0:0:0:1)로 나온다면 아래 내용을 참고하자
0:0:0:0:0:0:0:1 = localhost = 127.0.0.1
스프링에서 사용자(client) IP 가져오기
클라이언트의 IP 주소는 HttpServletRequest에 있는 getRemoteAddr( ) 메서드를 이용하여 알아낼 수 있다. 그러나 Proxy, Caching server, Load Balancer 등을 거쳐올 경우 getRemoteAddr( ) 를 이용하여 IP 주소를 가지고 오지 못하게 된다.
이럴경우 별도의 처리를 해주어야 한다.
private String getIp(HttpServletRequest request) { String ip = request.getHeader("X-Forwarded-For"); logger.info(">>>> X-FORWARDED-FOR : " + ip); if (ip == null) { ip = request.getHeader("Proxy-Client-IP"); logger.info(">>>> Proxy-Client-IP : " + ip); } if (ip == null) { ip = request.getHeader("WL-Proxy-Client-IP"); // 웹로직 logger.info(">>>> WL-Proxy-Client-IP : " + ip); } if (ip == null) { ip = request.getHeader("HTTP_CLIENT_IP"); logger.info(">>>> HTTP_CLIENT_IP : " + ip); } if (ip == null) { ip = request.getHeader("HTTP_X_FORWARDED_FOR"); logger.info(">>>> HTTP_X_FORWARDED_FOR : " + ip); } if (ip == null) { ip = request.getRemoteAddr(); } logger.info(">>>> Result : IP Address : "+ip); return ip; } | cs |
위의 코드를 이용하면 IP를 가져올 수 있다. 그런데 실행을 하고 나서 IP 주소가 이상하다면?
보통 로컬에서 테스트를 하면 IP 주소가 0:0:0:0:0:0:0:1 이렇게 나오게 된다. 보통 우리가 알고 있는 IP 주소라 하면 192.168.1.1 이런 식으로 4개의 숫자로 표시된다. 이런 방식은 IPv4의 방식이고, 0:0:0:0:0:0:0:1 이렇게 표시되는 것이 IPv6의 표시 방식이다.
기본적으로 로컬의 IP 주소를 가져오면 IPv6 형식으로 IP 주소를 가져오게 되므로 별도의 처리를 해야 한다.
※ 톰캣 사용자일 경우
STS나 이클립스를 실행시킨다. 그리고 상단 메뉴에서 [Run] - [Run Configurations] 를 선택한다.
왼쪽 메뉴에서 Tomcat Server at localhost 를 선택한다. 그리고 오른쪽 상단에서 (x)= Arguments 메뉴를 클릭한다.
다음으로 VM arguments 부분에 -Djava.net.preferIPv4Stack=true 를 추가하고 Apply를 클릭한다.
다시 소스 코드를 실행해 보면 IPv4 형식으로 IP 주소가 표시되는 것을 확인할 수 있다.
출처: http://all-record.tistory.com/168 [세상의 모든 기록]