'분류 전체보기'에 해당되는 글 80건

  1. 2019.06.27 springframework mvc i18n(국제화) and localization(지역화=현지화) by 파이팅야
  2. 2016.02.25 Unable to read data from the transport connection: 현재 연결은 원격 호스트에 의해 강제로 끊겼습니다. 오류 by 파이팅야
  3. 2015.02.03 [펌] JTDS&Mabatis 에서 MSSQL NVARCHAR 처리 by 파이팅야
  4. 2014.04.24 jquery validation에서 validation method에 많은 파라미터 보낼때 by 파이팅야
  5. 2014.04.18 jquery validation depends by 파이팅야
  6. 2014.04.17 jquery loading image by 파이팅야
  7. 2014.04.10 html base tag와 jquery ui tabs 사용시 오류 by 파이팅야
  8. 2014.04.07 (dialog 바깥쪽) click 시 jquery dialog 닫기 by 파이팅야
  9. 2014.02.05 git 관련 by 파이팅야
  10. 2014.02.04 thymeleaf 관련 by 파이팅야

국제화와 지역화

위키백과 내용 - https://ko.wikipedia.org/wiki/%EA%B5%AD%EC%A0%9C%ED%99%94%EC%99%80_%EC%A7%80%EC%97%AD%ED%99%94

국제화와 현지화는 출판물이나 하드웨어 또는 소프트웨어 등의 제품을 언어 및 문화권 등이 다른 여러 환경에 대해 사용할 수 있도록 지원하는 것을 의미한다. 이때 국제화는 제품 자체가 여러 환경을 지원할 수 있도록 제품을 설계하는 것을 의미하며, 현지화는 제품을 각 환경에 대해 지원하는 것을 의미한다.

 

최자의 보물창고 블로그 내용(신빙성은 적을 수 있음) - https://jwchoi85.tistory.com/tag/internationalization

컴퓨터에서 국제화와 현지화 라는것은, 다른 언어와 지역적인 차이들을 소프트웨어에 적용시킨다는 것을 말합니다. 국제화라는 것은 여러가지 다른 언어와 지역적 차이들을 기술적인 변경 없이 소프트웨어에 적용할 수 있도록 설계하는 과정을 말합니다. 현지화 라는 것은 국제화가 된 소프트웨어에 특정 지역이나 언어에 대해서 지역특색의 컴포넌트를 추가한다거나 번역을해서 적용시키는 것을 말합니다

 

 

LocaleResolver 종류

 

  • AceeptHeaderLocaleResolver (default)
    • 브라우저의 언어값으로 사용하는 것
    • HTTP 'Accept-Language' header값을 사용하는것
    • setLocale()메소르드를 지원하지 않음 사용하면 UnsupportedOperationException 발생함.
    • Locale aceeptHeaderLocale = new HttpServletRequest().getLocale();

  • CookieLocaleResolver
    • 쿠키 기반의 로케일 정도를 사용하는 것
    • <bean id="localeResolver"
          class="org.springframework.web.servlet.i18n.CookieLocaleResolver" >
          <property name="cookieName" value="clientlanguage"/>
          <property name="cookieMaxAge" value="100000"/>
          <property name="cookiePath" value="web/cookie"/>
      </bean>

    • 속성 설명

      프로퍼티 

      설 명  

       cookieName

       사용할 쿠키 이름

       cookieDomain

       쿠키 도메인

       cookiePath

       쿠키 경로, 기본값은 "/"이다.

       cookieMaxAge

       쿠키 유효 시간 (second), -1로 지정하면 브라우저를 닫을 때 쿠키를 지우겠다는 것

       cookieSecure

       보안 쿠키 여부, 기본값은 false 이다.

    • 만약 저장된 쿠키값이 없어서 특정값으로 세팅하고자 한다면 defaultLocale 파라미터값을 세팅하면 된다.

    • SessionLocaleResolver나 CookieLocaleResolver에 defaultLocale이 없다면 브라우저의 언어설정(AceeptHeaderLocaleResolver)을 따르게 된다.
    • CookieLocaleResolver에 보면 몇가지 추가 세팅할 수 있는 값이 있음
      • languageTagCompliant - Specify whether this resolver's cookies should be compliant with BCP 47 language tags instead of Java's legacy locale specification format. The default is falseNote: This mode requires JDK 7 or higher. Set this flag to true for BCP 47 compliance on JDK 7+ only.  
      • 위키백과의 내용과 같이 ko-KR과 같이 '_'가 아닌 '-'를 붙여서 표현하는 방식으로 쿠키값을 심을지 여부값 이다. true값이 되면 'ko-KR', 'en-US'와 같이 '-'가 들어간 형태로 cookieValue값이 세팅된다. springframework 내부적으로는 'ko_KR' 형식으로 사용하고 쿠키값(cookieValue)만 변경됨.
        • languageTagCompliant 값에 따른 parsing하는 코드
          • (isLanguageTagCompliant() ? Locale.forLanguageTag(locale) : StringUtils.parseLocaleString(locale))
      • Cookie 관련 정보(CookieGenerator class를 상속받아 cookie관련 설정값을 추가로 세팅 할 수 있음)
        • HttpOnly (CookieGenerator.cookieHttpOnly에 있는 값을 상속받음.) - javascript에서 document.cookie로 cookie값을 조작할 수 없도록 하고 웹서버에서만 cookie값을 조작할 수 있도록 할지 여부 값, 참고 링크 https://nsinc.tistory.com/121
        • secure (CookieGenerator.cookieSecure 에 있는 값을 상속받음) - HTTPS가 아닌 통신에서는 쿠키를 전송하지 않을지 여부 값. 참고 링크 https://nsinc.tistory.com/121
  • SessionLocaleResolver
    • 세션 기반의 로케일 정보를 사용하는 것
    • request가 가지고 있는 session에 있는 값을 가지고 오는 것
      <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />

    • 설정 예

    • <beans:bean id="localeResolver"

          class="org.springframework.web.servlet.i18n.SessionLocaleResolver">

          <beans:property name="defaultLocale" value="ko" />

      </beans:bean>

    • SessionLocaleResolver나 CookieLocaleResolver에 defaultLocale이 없다면 브라우저의 언어설정을 따르게 된다.

  • FixedLocaleResolver
    • 웹 요청과 상관없이 defaultLocale 속성값을 사용는 것
    • FixedLocaleResolver는 setLocale() 메소드를 지원하지 않음 호출하면  UnsupportedOperationException이 발생함.

Locale 변경시

  • LocaleResolver를 이용한 Locale 변경
    • LocaleResolver를 빈으로 등록했다면, 컨트롤러에서 LocaleResolver를 이용해서 Locale을 변경할 수 있게 된다. 예를 들어 다음과 같이 LocaleResolver를 설정했다고 하자.

    • <bean class="com.xxx.test.controller.LocaleChangeController">

              <property name="localeResolver" ref="localeResolver" />

      </bean>

      <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />

       

      이 경우, 컨트롤러 클래스는 다음과 같이 LocaleResolver의 setLocale() 메서드를 호출해서 클라이언트의 웹 요청을 위한 Locale을 변경할 수 있다.

    • import org.springframework.web.servlet.LocaleResolver;

      @Controller

      public class LocaleChangeController {

          private LocaleResolver localeResolver;

          @Inject

          public void setLocaleResolver(LocaleResolver localeResolver) {

              this.localeResolver = localeResolver;

          }

       

          @RequestMapping("/changeLocale")

          public String change(@RequestParam("language") String language, HttpServletRequest request, HttpServletResponse response) {

              // Locale locale = (isLanguageTagCompliant() ? Locale.forLanguageTag(locale) : StringUtils.parseLocaleString(locale))  // <-- CookieLocaleResolver를 사용 하는 경우

              Locale locale = new Locale(language);   // <-- cookie가 아닌 다른 LocaleResolver를 사용하는 경우

       

              // LocaleResolver localeResolver = RequestContextUtils.getLocaleResolver(request); // <-- DI를 받지 않고 현재 request에서 LocaleResolver를 가져올 수 도 있음.

       

              localeResolver.setLocale(request, response, locale);

              return "redirect:/index.jsp";

          }

      }

      LocaleResolver를 이용해서 Locale을 변경하면, 이후 요청에 대해서는 지정한 Locale을 이용해서 메시지 등을 로딩하게 된다.

      ResolverContextUtils는 현재 request에서 LocaleResolver를 가져올 수 있음.

  • LocaleChangeInterceptor를 사용하는 경우
    • org.springframework.web.servlet.i18n.LocaleChangeInterceptor는 url를 통해서 언어를 변경할 경우 사용 아래와 같은 설정 상태면 
    • <mvc:interceptors>

          <beans:bean id="localeChangeInterceptor" class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">

          <beans:property name="paramName" value="lang" />

          </beans:bean>

      </mvc:interceptors>

 

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/servlet/LocaleResolver.html

Posted by 파이팅야
,

.net HttpClient를 사용해서 외부 http API 호출하고 있는데

'Unable to read data from the transport connection: 현재 연결은 원격 호스트에 의해 강제로 끊겼습니다' exception이 발생하는 경우 


https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.10 문서의 내용보면  

'keep alive(persistence connection)를 하지 않을려면 Connection : Close를 명시적으로 붙여줘야 한다'는 내용이 있음

해당 내용을 보고 .net쪽 HttpClient library가 'Connection'header값이 없으면 keep alive로 동작하게 한것 같음 만약 아래코드가 없으면 keep-alive로 동작함

RequestHeaders headers = new RequestHeaders();

headers.Add("Connection", "close");

예전에도 비슷한 상황이 있었는데... 자꾸 까먹어 적어 놔야겠다. ㅋ

Posted by 파이팅야
,

MSSQL을 사용할 때
인덱스가 걸려있는 VARCHAR 컬럼데이터를 조회시 NVARCHAR로 데이터를 넘길경우
인덱스가 걸리지 않아 성능에 문제가 발생하는 사례가 존재한다.

(쿼리분석기에서는 빠른데 미들웨어에서 호출 시 느린경우)


 하여 보통은 jtds 드라이버 설정시
 sendStringParametersAsUnicode=false
 값을 주어 유니코드 처리하지 않게 함으로서 VARCHAR로 처리 되도록 하여 해결을 하고 있다.

 근데 문제는
 VARCHAR 와 NVARCHAR 가 섞여있을 경우에는 어떻게 해야 하는가?

 사실 이문제는 아래와 같이 풀면 해결이 될거라고 생각했다.

 1) 드라이버에서는 유니코드를 사용하지 않음 처리.
     - sendStringParametersAsUnicode=false
 2) mybatis mapper 에 jdbcType 을 부여
    - #{column, jdbcType=NVARCHAR}

 혹은 1)번을 부여하지 않고( default 는 sendStringParametersAsUnicode=true 이다. )
 #{column, jdbcType=NVARCHAR} 와 #{column, jdbcType=VARCHAR} 를 명시해주면 되지 않을까?

 라고 생각했었다.

 하지만, 결론은 안된다는거...

 그래서 jtds 드라이버 소스코드를 살펴 보았다.

 역시...NVARCHAR 사용을 위한 setNString() 에서 아래와 같은 코드로 구현이 되어있었고,

  [ JtdsCallableStatement.java ]

  public void setNString(String parameterName, String value)
            throws SQLException {
        // TODO Auto-generated method stub
        throw new AbstractMethodError();
    }

  public void setNString(int parameterIndex, String value)
            throws SQLException {
        // TODO Auto-generated method stub
        throw new AbstractMethodError();
    }

 실제 TdsData.java  ( getNativeType 메소드 ) , Support.java ( getJdbcTypeName 메소드 )내에서 지원가능한 jdbcType 검사를 하는데  여기에도 NVARCHAR 가 누락이 되어있다.

그럼 어떻게 NVARCHAR 를 지원하고 있었던걸까?

결론은 이렇다.

jtds 에서는 모든 NVARCHAR 든 VARCHAR 든 VARCHAR 로 인식하고 드라이버에 설정된 유니코드 사용여부에 따라 VARCHAR를 변환하고 있었던 것이다.

'모' 아니면 '도' 로 말이다.

그렇다면 이부분을 어떻게 해결할 수 있을까?

답은 간단하다.

setNString 구간에 setString 을 참조하여 내용을 체워주고,

JtdsPreparedStatement.java ]
protected void setParameter(int parameterIndex, Object x, int targetSqlType, int scale, int length)

메소드에 NVARCHAR 타입일 경우 pi.isUnicode = true 로 부여하면,

mybatis에서 NVARCHAR 로 jdbcType 을 부여한 것에 대해서 처리가 가능하다.

이때, mybatis 부분도 수정이 필요한데 이유는 이렇다.

mybatis 의 NVARCHAR 를 처리하는 NStringTypeHandler 라는 클래스가 존재하는데

이 클래스에서 파라미터 바인딩시 setString 이 호출되게 되어있다.

이걸 setNString 을 호출하게 변경하면, 정상처리가 되게 되는 것이다.


이번 기회에 jtds 내에서 어떤 일이 일어나는지 알게된 점이 좋았던거 같다.

그리고 왜 NVARCHAR 를 지원하지 않게 되어있는지...그리고 mybatis에서도 왜 NStringTypeHandler 에서도

setNString 이 아니라 setString 으로 되어있었는지에 대해서는 좀더 고민을 해봐야 할듯하다.

이유가 없지는 않을테니 말이다.

여하튼 이렇게 VARCHAR 와 NVARCHAR 을 Mix 에서 사용하는 곳에서는
이런 부분도 고려가 되어야 할듯하다.




출처 : http://ymseok.blogspot.kr/2013/07/jtds-mssql-nvarchar.html

Posted by 파이팅야
,

날짜값이 N만큼 차이 나는지 확인하는 validation method 추가 시

(첫번째 parameter값인 'param[0]'에 에러메시지의 '{0}'값이 있어야 함)

// Validation Method

jQuery.validator.addMethod("datetimeDiffOver", function(value, element, param) {

        var startDate = $(param[1]).datetimepicker('getDate');

        var endDate = $(param[2]).datetimepicker('getDate');

        var diffDays = Math.ceil((endDate.getTime() - startDate.getTime()) / (1000 * 60 * 60 * 24)) - 1;

        return diffDays <= param[0];

}, '검색 기간을 {0}일이하로 설정해 주시기 바랍니다.');

 

// Validator

var searchValidator= $("#frmSearch").validate({

        rules: {

               searchStart : {

                       datetimeDiffOver : [30, '#txtSearchStart', '#txtSearchEnd']

               }

        }

});


Posted by 파이팅야
,


아래 코드 처럼 사용하지 말고

// validation method 추가

jQuery.validator.addMethod("guid", function(value, element, param) {

        var searchVal = $.trim($(element).val());

       

        if ($(param).val() == "Guid" && searchVal != "") {

               var re = /^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$/;

               return re.test(searchVal);

        }

        return true;

}, 'GUID 형식에 맞게 입력해주세요.');


// 검색용 Validator

var searchValidator= $("#frmSearch").validate({

        rules: {

               searchValue : {

                       maxlength: 50,

                       guid : "#sltSearchType"

               }

        }

});



아래 코드처럼 사용해야 'guid' validation method의 재 사용성이 커진다.

// validation method 추가

jQuery.validator.addMethod("guid", function(value, element, param) {

        var searchVal = $.trim($(element).val());

        var re = /^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$/;

        return re.test(searchVal);

}, 'GUID 형식에 맞게 입력해주세요.');


// 검색용 Validator

var searchValidator= $("#frmSearch").validate({

        rules: {

               searchValue : {

                       maxlength: 50,

                       guid : {

// param : [1, 'a']    // param값 셑팅 시 사용

                              depends : function(element) {

                                      // 검색조건이 guid이고 검색내용이 있는경우 GUID 유효한지 확인

                                      return $("#sltSearchType").val() == "Guid"

                                             && $.trim($(element).val()) != "";

                              }

                       }

               }

        }

});


참고 URL

http://jqueryvalidation.org/validate#rules

Posted by 파이팅야
,

jquery loading image

Javascript 2014. 4. 17. 17:31

AJAX event 순서가 https://api.jquery.com/Ajax_Events/ 와 같으니

$(document).ready(function() {

        // loading image <body> 추가

        $('img')

               .attr("id", "loading")

               .attr("src", "resources/images/loading_image.gif")

               .css("position", "absolute")

               .css("left", "47%")    // 50%로하고 margin-xxx 넣거나 left,top 적당 비율로 넣기

               .css("top", "47%"// body,screen,window 기준에 따라서 중간 위치값이 달라질듯

               //.css("margin-left", "-17px") // [image width / 2]

               //.css("margin-top", "-17px") // [image width / 2]

               .css("display", "none")

               .fadeTo(0, 0.7) // for opacity filter

               .appendTo("body");

});


모든 ajax에 적용 시

$(document).ajaxSend(function() {

        $("#loading").show();

});

$( document ).ajaxComplete(function() {

        $( "#loading" ).hide();

});


특정 ajax만 적용 시

// 서버 목록 조회 tab 추가

$.ajax({

        url: "server/list",

        beforeSend : function () {

               $("#loading").show();

        },

        complete : function() {

               $( "#loading" ).hide();

        },

});



AJAX event 순서

  • ajaxStart (Global Event)
    This event is triggered if an Ajax request is started and no other Ajax requests are currently running.
    • beforeSend (Local Event)
      This event, which is triggered before an Ajax request is started, allows you to modify the XMLHttpRequest object (setting additional headers, if need be.)
    • ajaxSend (Global Event)
      This global event is also triggered before the request is run.
    • success (Local Event)
      This event is only called if the request was successful (no errors from the server, no errors with the data).
    • ajaxSuccess (Global Event)
      This event is also only called if the request was successful.
    • error (Local Event)
      This event is only called if an error occurred with the request (you can never have both an error and a success callback with a request).
    • ajaxError (Global Event)
      This global event behaves the same as the local error event.
    • complete (Local Event)
      This event is called regardless of if the request was successful, or not. You will always receive a complete callback, even for synchronous requests.
    • ajaxComplete (Global Event)
      This event behaves the same as the complete event and will be triggered every time an Ajax request finishes.
  • ajaxStop (Global Event)
    This global event is triggered if there are no more Ajax requests being processed.

사용 예


Posted by 파이팅야
,

- html base tag를 사용하면 jquery ui tabs가 제대로 동작하지 않는다.
- base tag에 넣은 url 정보값을 참조해서 href나 src등의 속성값에서 상대적으로 참조하게 된다.
ex> <base href="/aaa/bb"> 이고 <a href="x.html">link</a> 인 경우 link의 url은 /aaa/bb/x.html인 된다.
base tag 관련 - http://www.w3schools.com/tags/tag_base.asphttp://www.tutorialspoint.com/html/html_base_tag.htm


- 관련 내용 및 해결 방법
http://bugs.jqueryui.com/ticket/8637

- 해결방법은 jquery.ui.tabs 쓰기 전 아래의 함수를 넣거나 href, src 부분에 full url정보를 넣는 2가지 방법이 있을것 같다. 나중에 개발자가 신경쓰지 않을려면 view template layout(.net의 master page)등에 아래의 함수를 두면 될것 같다.

$.fn.__tabs = $.fn.tabs;
$.fn.tabs = function (a, b, c, d, e, f) {
    var base = location.href.replace(/#.*$/, '');
    $('ul>li>a[href^="#"]', this).each(function () {
        var href = $(this).attr('href');
        $(this).attr('href', base + href);
    });
    $(this).__tabs(a, b, c, d, e, f);
};


Posted by 파이팅야
,

modal인 경우

$(document).ready(function() {

    $("#dialog").dialog({

        bgiframe: true,

        autoOpen: false,

        height: 100,

        modal: true,

        open: function() {

        $('.ui-widget-overlay').off('click');

        $('.ui-widget-overlay').on('click', function() {

                $('#dialog').dialog('close');

            })

        }

    });

});


modal이 아닌 경우

// id가 btnServiceList button 클릭 시 divServiceList dialog 보여줄때

$(document).ready(function() {

$("#divServiceList").dialog(

    { modal: false },

    {open : function() {

        $('body').off("click");

        $('body').on("click", function(e){

            if($('#divServiceList').dialog('isOpen')

                       && !$(e.target).closest('#btnServiceList').length

                       && !$(e.target).is('.ui-dialog, a')

                       && !$(e.target).closest('.ui-dialog').length

                       ){

                        $('#divServiceList').dialog('close');

            }

        });

    }},

    {close : function() {

        $('body').off("click");

    }}

);

}


Posted by 파이팅야
,

git 관련

풀그림 2014. 2. 5. 20:36
Posted by 파이팅야
,

thymeleaf 관련

기타 2014. 2. 4. 17:52


관련 expression

l  Simple expressions:

n  Variable Expressions: ${...}

n  Selection Variable Expressions: *{...}

u  사용 예 (th:object와 같이 선택[selection] 되어 있어야 한다.)

l  <div th:object="${session.user}">

l      <p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>

l  </div>

n  Message Expressions: #{...}

n  Link URL Expressions: @{...}

l  Literals

n  Text literals: 'one text', 'Another one!',...

n  Number literals: 0, 34, 3.0, 12.3,...

n  Boolean literals: true, false

n  Null literal: null

n  Literal tokens: one, sometext, main,...

l  Text operations:

n  String concatenation: +

n  Literal substitutions: |The name is ${name}|

l  Arithmetic operations:

n  Binary operators: +, -, *, /, %

n  Minus sign (unary operator): -

l  Boolean operations:

n  Binary operators: and, or

n  Boolean negation (unary operator): !, not

l  Comparisons and equality:

n  Comparators: >, <, >=, <= (gt, lt, ge, le)

n  Equality operators: ==, != (eq, ne)

l  Conditional operators:

n  If-then: (if) ? (then)

n  If-then-else: (if) ? (then) : (else)

n  Default: (value) ?: (defaultvalue)

u  valuenull이면 deaufltvalue값을 사용하고 아니면 value값을 사용함

n  사용 예

u  'User is of type ' + (${user.isAdmin()} ? 'Administrator' : (${user.type} ?: 'Unknown'))


springframework과 연동하면

  • th:field <select><input><textarea>등에 넣으면 자동 binding
  • *{{newDate}}와 같이 double-bracket syntax를 사용하면 Spring Conversion Service가 자동 연동 된다.


참고내용

1.     기본적으로 볼 것(springframework을 사용하면 아래 2개는 모두 보고 사용하길 추천함

두번째 링크에서 활용도 높은 새로운 기능 및 tag들이 있음)

A.     http://www.thymeleaf.org/

B.      Using Thymeleaf - http://www.thymeleaf.org/doc/html/Using-Thymeleaf.html

C.      Thymeleaf + spring 3 - http://www.thymeleaf.org/doc/html/Thymeleaf-Spring3.html

2.     참고로 볼 것

A.     http://en.wikipedia.org/wiki/Thymeleaf

B.      http://www.thymeleaf.org/thvsjsp.html

C.      http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-4.dtd

D.     http://forum.thymeleaf.org/

E.      18. View technologies – Spring - http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/view.html




Posted by 파이팅야
,