差分
このページの2つのバージョン間の差分を表示します。
| 次のリビジョン | 前のリビジョン | ||
| study:jsf:logging [2008/04/13 14:02] – created banana | study:jsf:logging [2008/04/13 15:52] (現在) – banana | ||
|---|---|---|---|
| 行 46: | 行 46: | ||
| return text; | return text; | ||
| } | } | ||
| + | ... | ||
| </ | </ | ||
| + | |||
| + | ---- | ||
| + | |||
| 이 코드는 **getCurrentClassLoader**라는 메소드로 시작하는데, | 이 코드는 **getCurrentClassLoader**라는 메소드로 시작하는데, | ||
| 또는 지정된 기본 객체의 클래스 로더를 리턴한다. \\ 클래스 로더가 왜 필요할까? | 또는 지정된 기본 객체의 클래스 로더를 리턴한다. \\ 클래스 로더가 왜 필요할까? | ||
| 行 59: | 行 63: | ||
| 파라미터의 배열이 들어있다면 **%%MessageFormat%%** 클래스를 사용하여 파라미터들을 문자열에 삽입한다. | 파라미터의 배열이 들어있다면 **%%MessageFormat%%** 클래스를 사용하여 파라미터들을 문자열에 삽입한다. | ||
| + | 이제 실제 코드에서 이 Utils 메소드를 사용하는 예를 보인다. | ||
| + | {{keywords> | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ===== Example of using Utils.getDisplayString ===== | ||
| + | 이 예제는 Custom 보안을 위한 Filter 클래스의 일부이다. | ||
| + | <code java> | ||
| + | public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | ||
| + | throws IOException, | ||
| + | ... | ||
| + | HttpServletRequest httpRequest = (HttpServletRequest)request; | ||
| + | HttpServletResponse httpResponse = (HttpServletResponse)response; | ||
| + | HttpSession session = httpRequest.getSession(); | ||
| + | |||
| + | String requestPath = httpRequest.getPathInfo(); | ||
| + | ... | ||
| + | String text = Utils.getDisplayString(Constants.BUNDLE_BASENAME, | ||
| + | " | ||
| + | new Object[] { requestPath }, | ||
| + | | ||
| + | httpResponse.sendError(HttpServletResponse.SC_NOT_FOUND, | ||
| + | ... | ||
| + | </ | ||
| + | 먼저 주목해야 할 것은 이름을 잘못 코딩하는 것을 막기 위해 리소스 번들의 이름을 Costants 클래스로부터 가져온다는 사실이다.\\ | ||
| + | 또한 현재의 Locale을 직접 %%HttpRequest%%객체로부터 가져왔는데, | ||
| + | 번들 내의 문자열이 하나의 파라미터를 포함하고 있으므로 **getDisplayString** 메소드에 하나의 파라미터로서 requestPath를 | ||
| + | 전달한다.((이로써 " | ||
| + | ---- | ||
| + | 이번에는 코드에서 Component의 text를 국제화시키는 예이다. | ||
| + | <code java> | ||
| + | public HtmlSelectOneMenu getProjectSelectOne() | ||
| + | { | ||
| + | if (projectSelectOne == null) | ||
| + | { | ||
| + | ... | ||
| + | // projectSelectOne.setTitle(" | ||
| + | projectSelectOne.setTitle( | ||
| + | Utils.getDisplayString(getApplication().getMessageBundle(), | ||
| + | " | ||
| + | null, | ||
| + | | ||
| + | ... | ||
| + | return projectSelectOne; | ||
| + | } | ||
| + | </ | ||
| + | 이번에는 JSF API를 사용할 수 있으므로, | ||
| + | **Application.messageBundle** 특성은 faces-config.xml에 설정돼 있는 번들을 리턴한다. \\ | ||
| + | **faces-config.xml**은 커스터마이징된 메세지를 위한 용도도 있지만 표시 문자열을 지역화 하기 위해 사용될 수도 있다.\\ | ||
| + | **faces-config.xml**에는 오직 하나의 번들만을 지정할 수 있다. 따라서 Application이 다수의 번들을 가지고 있다면, | ||
| + | 앞의 예제와 같이 문자열 상수를 사용하여 번들을 로드해야 한다.\\ | ||
| + | 이 문자열은 파라미터를 갖지 않으므로 getDisplayString 메소드의 파라미터 배열에 null을 전달했다. | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ====== Internalization of Messages ====== | ||
| + | 이번에는 코드내에서 정보를 알리기 위한 목적과 에러를 보고하기 위한 목적등으로 쓰이는 메세지를 생성하는 Utils 메소드를 소개한다.\\ 이 메소드는 %%ResourceBundle%%로부터 새로운 %%FacesMessage%% 인스턴스를 생성시키는 Factory method이다. | ||
| + | ((우리는 몇 개의 파라미터를 받는 하나의 팩토리 메소드를 작성했다. 기본적으로 사용할 수 있는 편리한 메소드를 작성해 놓는것이 | ||
| + | 좋을 것이기 때문에, 이 메소드에서는 locale이나 severity같은 파라미터를 지정하지 않았다. 만약 이런 메소드를 직접 작성하기를 | ||
| + | 원하지 않는다면, | ||
| + | <code java> | ||
| + | ... | ||
| + | public static FacesMessage getMessage(String messageId, Object params[], | ||
| + | FacesMessage.Severity severity) | ||
| + | { | ||
| + | FacesContext facesContext = FacesContext.getCurrentInstance(); | ||
| + | String bundleName = facesContext.getApplication().getMessageBundle(); | ||
| + | if (bundleName != null) | ||
| + | { | ||
| + | String summary = null; | ||
| + | String detail = null; | ||
| + | Locale locale = facesContext.getViewRoot().getLocale(); | ||
| + | ResourceBundle bundle = | ||
| + | ResourceBundle.getBundle(bundleName, | ||
| + | | ||
| + | try | ||
| + | { | ||
| + | summary = bundle.getString(messageId); | ||
| + | detail = bundle.getString(messageId + " | ||
| + | } | ||
| + | catch (MissingResourceException e) | ||
| + | {} | ||
| + | if (summary != null) | ||
| + | { | ||
| + | MessageFormat mf = null; | ||
| + | if (params != null) | ||
| + | { | ||
| + | mf = new MessageFormat(summary, | ||
| + | summary = mf.format(params, | ||
| + | } | ||
| + | if (detail != null && params != null) | ||
| + | { | ||
| + | mf.applyPattern(detail); | ||
| + | detail = mf.format(params, | ||
| + | } | ||
| + | return (new FacesMessage(severity, | ||
| + | } | ||
| + | } | ||
| + | return new FacesMessage(severity, | ||
| + | null); | ||
| + | } | ||
| + | } | ||
| + | ... | ||
| + | public static void reportError(FacesContext facesContext, | ||
| + | | ||
| + | { | ||
| + | FacesMessage message = getMessage(messageId, | ||
| + | | ||
| + | facesContext.addMessage(null, | ||
| + | if (exception != null) | ||
| + | { | ||
| + | facesContext.getExternalContext().log(message.getSummary(), | ||
| + | } | ||
| + | } | ||
| + | ... | ||
| + | </ | ||
| + | 새로운 **getMessage** 메소드는 **getDisplayString**과 비슷하다. 다만 요약문과 상세문에 따른 새로운 **%%FaceMessage%%** | ||
| + | 인스턴스를 생성시킨다는 점이 다르다. \\ | ||
| + | 두 식별자의 유일한 차이는 상세문의 경우 " | ||
| + | 다루는 방식이다.\\ | ||
| + | **reportError**는 식별자에 근거하여 메세지를 로드하는 getMessage를 사용한다. | ||
| + | |||
| + | 새로운 팩토리 메소드를 정의했으므로, | ||
| + | |||
| + | |||
| + | |||
| + | |||
| + | ===== Example of using Utils.getMessage and Utils.reportError ===== | ||
| + | <code java> | ||
| + | public String login() | ||
| + | { | ||
| + | FacesContext facesContext = getFacesContext(); | ||
| + | Utils.log(facesContext, | ||
| + | |||
| + | User newUser = null; | ||
| + | try | ||
| + | { | ||
| + | newUser = getUserCoordinator().getUser(loginName, | ||
| + | } | ||
| + | catch (ObjectNotFoundException e) | ||
| + | { | ||
| + | facesContext.addMessage(null, | ||
| + | Utils.getMessage(" | ||
| + | | ||
| + | |||
| + | /* facesContext.addMessage(null, | ||
| + | new FacesMessage(FacesMessage.SEVERITY_WARN, | ||
| + | " | ||
| + | return Constants.FAILURE_OUTCOME; | ||
| + | } | ||
| + | catch (DataStoreException d) | ||
| + | { | ||
| + | | ||
| + | |||
| + | /* Utils.reportError(facesContext, | ||
| + | " | ||
| + | return Constants.ERROR_OUTCOME; | ||
| + | } | ||
| + | ... | ||
| + | </ | ||
| + | 변경된 부분의 getUser를 호출한 뒤 예외를 처리하는 곳이다. **%%ObjectNotFoundException%%**은 중요한 에러가 아니므로, | ||
| + | 이 경우 %%BadLogin%%이라는 식별자와 함께 **getMessage** 메소드를 사용하여 INFO 수준의 심각도를 갖는 메세지를 추가했다.\\ | ||
| + | **%%DataStoreException%%**은 심각한 에러이기 때문에, %%ErrorLoginUser%% 식별자와 함께 **reportError**를 호출했다. | ||
| + | ((코드 내에서 메세지를 생성시키는 것은 많은 양의 작업을 필요로 한다. %%FacesMessage%%를 위한 팩토리 메소드는 우리가 직접 작성할 것이 아니라 표준 API의 일부여야 한다고 생각한다. JSF의 차기 버전에서는 이것이 반영되기를 희망한다.)) | ||