개발노트/TroubleShooting

[Spring] 다국어 처리 시 locale이 제대로 처리되지 않는 문제

dev-mylee 2025. 2. 13. 10:59

문제 상황

로그인 실패 이력을 보여주는 그리드에서 실패 사유를 다국어 처리하려고 했다.

최초에는 jqGrid formatter에서 직접 다국어 처리를 시도:

colModel:[
    {name:'failReason', index:'failReason', width:300, align:"left",
        formatter: function(cellvalue){
            // spring:message를 직접 사용하려 했으나 JavaScript에서는 불가능
            return '<spring:message code="' + cellvalue + '"/>';  // 작동 안함
        }
    }
]

 

알고보니 spring:message는 JSP 처리 단계에서 서버 사이드로 처리되고,

formatter는 그 이후 클라이언트 사이드에서 실행되기 때문에 동작할 수가 없었다.

 

spring:message가 처리되는 시점:

  1. 서버에서 JSP 파일 처리
  2. spring:message 태그를 실제 메시지로 변환
  3. 변환된 HTML을 클라이언트로 전송

formatter가 실행되는 시점:

  1. 클라이언트에서 HTML 로드
  2. jqGrid JavaScript 코드 실행
  3. 데이터 바인딩 시 formatter 함수 호출

이런 처리 순서 때문에 JavaScript에서는 이미 서버 사이드 처리가 끝난 후라 spring:message를 사용할 수 없다는 것을 알게 되었다.

(spring:message code="cellvalue"로 하드코딩 되어져서 인식됨...)

 

 

서비스단에서 MessageSource를 이용하는 방식으로 변경:

@Autowired
MessageSource messageSource;

public Map<String, Object> selectLoginHistory(LoginHistoryVo historyVo) {
    List<LoginHistoryVo> list = loginHistoryMapper.selectLoginHistory(historyVo);
    
    Locale locale = LocaleContextHolder.getLocale();
    for(LoginHistoryVo history : list) {
        String failReason = history.getFailReason();
        if(failReason != null) {
            String message = messageSource.getMessage(failReason, null, failReason, locale);
            history.setFailReason(message);
        }
    }
    // ... 
}

 

서버에서 처리했더니 다음과 같은 문제들이 발생:

  1. 언어 변경 시 세션의 locale이 제대로 유지되지 않음
  2. AJAX 호출 시 language 파라미터 관리가 복잡
  3. 동적 데이터 처리가 어려움

 

최종 해결 방법

JSP에서 spring:message로 메시지를 미리 준비해두고, jqGrid formatter에서 해당 메시지를 사용하는 방식으로 변경했다.

1. JSP에서 메시지 준비:

<div style="display:none;">
    <span id="error.msg.login.user.not.found">
        <spring:message code="error.msg.login.user.not.found"/>
    </span>
    <span id="error.msg.login.password.not.match">
        <spring:message code="error.msg.login.password.not.match"/>
    </span>
</div>

 

DB에서 조회해온 code(다국어 처리 key)를 동적으로 불러오고 싶었지만 실패 ㅠㅠ

 

2. jqGrid formatter에서 메시지 사용:

colModel:[
    {name:'failReason', index:'failReason', width:300, align:"left",
        formatter: function(cellvalue){
            if(!cellvalue) return '';
            var escapedId = cellvalue.replace(/\./g, '\\.');
            var translatedMsg = $('#' + escapedId).text();
            return translatedMsg || cellvalue;
        }
    }
]

 

 

 

핵심 포인트

  • JavaScript에서는 spring:message를 직접 사용할 수 없음
  • 서버에서의 MessageSource 처리는 locale 관리가 복잡해짐
  • JSP 렌더링(spring:message 처리) → JavaScript 실행(jqGrid) 순서로 처리됨
  • 메시지를 미리 준비해두고 formatter에서 가져다 쓰는 방식이 가장 안정적

 

주의사항

  • ID 셀렉터에 특수문자(.)가 있어서 jQuery 셀렉터 에러가 날 수 있음
  • escape 처리 필수
  • 빈 값 처리도 고려해야 함