RestTemplate 사용 시 파라미터 값이 자동으로 인코딩 되는 현상을 발견하게 되었다.전송되는 URL은 다음과 같은데 파라미터 값에 특수문자들이 들어간다.http://api.com?param=ABCDE+=,$%ABCDE 이와 같이 상대 서버로 요청을 보내면 파라미터 값에 ABCDE+=,$%ABCDE 가 들어 있어야 하는데 인코딩된 값으로 전달 된다고 한다.실제 개발되어져 있는 코드를 보면 인코딩한 흔적이 없었다.구글 검색을 해보니 url 을 넘겨주는 아규먼트가 String 타입이면 URL 인코딩이 자동으로 발생한다고 설명되어져 있다.정말로 그런지 확인을 위해서 테스트 코드를 작성해 보았다.테스트 코드에 나와 있는 것 처럼 url 을 넘겨주는 아규먼트에 uri.toString() 과 같이 String..
다음과 같은 코드가 있다고 하자. @GetMapping("/completeGift") public ModelAndView completeGift() { return new ModelAndView("redirect:/"); } 사용자가 https://myservice.com/completeGift 페이지를 호출했다면 리다이렉트가 될 것이다. 우리가 예상하는 페이지는 당연히 https://myservice.com 가 될 것이다. 하지만 예상과는 다르게 http://myservice.com 페이지로 호출하게 된다. 차이점이 보이는가? 프로토콜이 달라지는 것을 알 수 있다. https 사이트에서 http 사이트로 페이지 리다이렉트 됐다. 우리는 대게 서비스를 오픈하게 되면 http://myservice.com ..
SimpleDateFormat 클래스는 쓰레드 세이프 하지 않기 때문에 사용할 때 주의를 해야 한다. 다음은 쓰레드 10개를 실행시켜 SimpleDateFormat의 parse("20150630") 메서드를 동시에 실행시키는 테스트 코드이다. 위의 코드를 실행해 보면 다음과 같이 정상적으로 테스트가 종료되는 경우가 있고, 오류가 발생되는 케이스가 있다. 출력된 로그에 나와 있는 것처럼 테스트 코드에서 의도한 Tue Jun 30 00:00:00 KST 2015 값만 노출되는 것이 아닌 이상한 날짜가 출력되고 있는 것을 볼 수 있다. 이는 Thread safe하지 않은 상태에서 여러 쓰레드가 SimpleDateFormat 을 사용하게 됨으로써 발생되는 현상이다. 오류가 발생하면 그나마 다행이지만 가장 큰 우..
HTTP POST 방식으로의 Request 요청 시 서블릿에서 getParameter("data")를 이용하여 데이터를 뽑아 올 때 주의사항이 있다.내가 삽질했던 내용을 적어보면 다음과 같다.서버 코드의 Controller에 다음의 request handler mapping이 정의되어 있다.@RequestMapping(value = "/test", method = RequestMethod.POST)@ResponseBodypublic String test(HttpServletRequest request) {String reqData = request.getParameter("data");return "success";} 위에 작성되어 있는 handler가 정상 동작하는지에 대해서 테스트 코드를 작성한 후 ..
로그인 되어 있는 상태에서 다음의 메소드를 Async 방식으로 호출한 후 로그인 사용자의 계정 정보를 추출하면 항상 null 값이 나온다.@Asyncpublic void searchLog(Search search) {Authentication auth = SecurityContextHolder.getContext().getAuthentication();String userId = auth.getName();} 스프링 시큐리티는 사용자 인증 후 ThreadLocal 객체에 값을 저장하기 때문에 @Async 기능으로 인한 새로운 쓰레드에서는 사용자 세션 정보를 가져올 수 없다.-> spring security 필터를 통과한 쓰레드만 사용자 로그인 정보를 ThreadLocal에 담는다.
HTTP request 시 json 스트링을 서버에 넘겨주고, 서버는 interceptor에서 먼저 HTTP request body에 있는 json 스트링을 읽어와 값에 대한 체크를 진행하는 로직을 개발하고 있었다. json 스트링 검증 후 spring controller에서 @RequestParam 으로 데이터를 받으려고 할 때 다음과 같은 예외가 발생java.lang.RuntimeException: java.io.EOFException: No content to map to Object due to end of input interceptor에서 request body의 데이터를 이미 읽어 들였기 때문에 나오는 증상이다.시퀀스 다이어그램으로 표현하자면 다음의 4번에 해당하는 부분에서 예외가 발생된다...
다음과 같이 self closing을 사용하여 외부 자바스크립트를 불러오게 되면 문제가 발생한다.문제라 함은 브라우저에서 해당 외부 자바스크립트의 함수를 호출하지 못하는 것.self closing이란 와 같은 문법을 말한다. Start tag는 존재하지만 End tag는 존재하지 않는 것이다. 여하튼 개발을 하다 이와 같은 문제를 겪게 되었고 왜 브라우저가 정상적으로 자바스크립트를 로딩하지 못하는지에 대해서 확인을 해보았다. self closing 은 원래 XHTML 에서 사용하는 문법이라고 하며 다음과 같이 엘리먼트를 꼭 slash를 이용하여 self-closing해야 한다고 적혀 있다.XHTML requires that tags like and get an extra slash to make them..
간혹 스프링 트랜잭션을 적용하였는데 예외 발생 시 롤백이 되지 않을 때가 있다.안되는 이유야 여러 가지가 있겠지만 난 그 중 한 가지 문제에 대해서 작성하려고 한다. 일단 테스트하는 스프링 애플리케이션 컨텍스트의 트랜잭션 AOP 설정은 다음과 같이 선언적 트랜잭션을 사용하였다.service 패키지 하위에 있는 모든 클래스 중 insert*, delete*, update* 이름에 매칭되는 메소드에 트랜잭션 설정 테스트 코드는 다음과 같다.문제가 발생되는 원인에 대해서 보여주려고 실패 case에 대한 메소드를 생성하였다.@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {"/test-application-context.xml"}..
스프링의 트랜잭션 AOP는 기본적으로 서비스 계층의 interface를 JDK 다이내믹 프록시 기술을 이용하여 AOP를 지원하지만 인터페이스가 없다면 CGLib를 이용하여 클래스 프록시를 생성한다. 만약 CGLib를 이용한 클래스 프록시를 사용한다면 클래스 패스의 라이브러리에 cglib-x.x.jar 가 있어야 한다. 주의 사항은 final 클래스에는 클래스 프록시를 적용할 수 없다는 것이다.클래스 프록시는 타깃 클래스를 상속해서 프록시를 만들기 때문에 상속을 할 수 없는 final 클래스에는 적용하지 못한다. 또한, 클래스 프록시를 적용하면 클래스의 생성자가 두 번 호출된다. 첫 번째 생성자 호출 로그 (프록시 오브젝트)create bean : com.kyu.svc.component.user.servi..
스프링에서는 예외 발생 시 HandlerExceptionResolver가 예외를 처리하도록 위임할 수 있다. 그래서 난 아래와 같이 SimpleMappingExceptionResolver를 정의한 후 예외 종류에 따라서 사용자에게 보여주는 화면을 달리하였다.common/error/businessLogicErrorcommon/error/runtimeErrorcommon/error/defaultErrorcommon/error/defaultError 헌데, HTTP 404에 대한 예외 처리는 SimpleMappingExceptionResolver에서 처리를 하지 못한다. 스프링의 @RequestMapping 애노테이션에 정의되지 않은 http://localhost:8080/notFoundRequestMappi..
사용자 개인 정보를 서버에 전송할 때 HTTPS로 적용해 달라는 요청이 들어온 적이 있었다.그래서 주민등록번호나 회원 아이디, 패스워드 등을 서버로 전송하는 페이지에 한해서 HTTPS로 적용되게 URL을 변경하였다. 헌데, 다음과 같은 문제가 발생하였다.1. 회원 약관 페이지 접근 http://test.co.kr/userAgreement.do2. 약관 페이지에서 회원 정보 입력 페이지 이동 https://test.co.kr/userReg.do3. 회원 정보 입력 페이지에서 휴대폰 인증 버튼 클릭 시 ajax로 http://test.co.kr/userAuthMobilePhone.do 요청 위와 같이 휴대폰 인증 버튼 클릭 시 서버로 요청을 보내지도 못하고, ajax 에러 메시지가 출력된다.error, No..
공통 상수 값을 인터페이스에 정의하는 이유가 예전부터 궁금했었다.처음에는 메소드가 필요 없어서 interface로 설계를 했나라고 그러려니 했었는데 다른 사람이 만들어놓은 소스를 보다보니 그 이유를 알게 되었다. 아래 코드는 다른 사람이 작성한 코드의 일부분이다.public class MdnChangeServlet extends HttpServlet implements CodeDefinition { CodeDefinition 인터페이스에는 static 상수 값이 정의되어 있고, MdnChangeServlet에서 상수 값을 사용하기 위해 인터페이스를 구현했다.static으로 정의되어 있는 상수 값을 굳이 인터페이스 구현을 통해서 사용하려는 목적은 CodeDefinition.IS_CHECK 와 같이 코드를 ..