이전 기사에 작성된 기사 : 오랫동안이 기사는 주로 일부 프로젝트에서 발생하는 실제 문제와 해당 솔루션을 기록합니다. 해당 코드를 분석 할 때 문제를 직접 지적하고 관련없는 프로세스 코드를 게시하지 않습니다. 관심있는 독자는 스스로 추적 할 수 있습니다. 동시에, 나는 모든 사람들이 의견 영역에서 자신의 경험을 공유하여 모든 사람이 함께 진전을 이룰 수 있기를 바랍니다!
환경 또는 버전 : 스프링 3.2.3
현상 : Spring의 자체 MessessOURCE는 국제 카피 라이팅을 처리하는 데 사용됩니다. 미국 주 카피 라이팅의 일부 장소 보유자는 대체되지 않았으며 이는 CN 주에서 정상입니다. 카피 라이팅은 다음과 같습니다.
tms.pallet.order.box.qty = 총 팔레트 상자 수량 {0} 수신 상자 수량 {1}과 일치하지 않으면 이중 확인하십시오!
tms.pallet.order.box.qty = 탑승을위한 총 상자 수 {0}. 주문 영수증 {1}의 총 상자 수와 일치하지 않습니다. 확인하세요!
직관 : 영어 카피 라이팅이 너무 길습니까? 스프링은 처리 할 때 길이를 제한했습니다. 신중하게 생각한 후에는 봄이 그렇게 불쌍하지 않아야합니다.
문제 해결 : 브레이크 포인트 추적 스프링 소스 코드 (Entrysource GetMessage Method)를 추적하고 마침내 MessageFormat에서 이와 같은 처리 메소드를 발견했습니다.
// 세그먼트의 지수 개인 정적 최종 최종 int seg_raw = 0; 개인 정적 최종 최종 int seg_index = 1; 개인 정적 최종 최종 int seg_type = 2; 개인 정적 최종 최종 int seg_modifier = 3; // modifier 또는 subformat/***이 메시지 형식에서 사용되는 패턴을 설정합니다. *이 메소드는 패턴을 구문 분석하고 포함 된 형식 요소에 대한 서브 포름 * 목록을 만듭니다. * 패턴과 해석은 * <a href = "#patterns"rel = "external nofollow"> 클래스 설명 </a>에 지정됩니다. * * @Param 패턴이 메시지 형식의 패턴 * @Exception 불법 행위 exception 패턴이 유효하지 않은 경우 */ @SuppressWarnings ( "allterrough") // 스위치의 러프가 예상됩니다. 공개 void ApplyPattern (문자열 패턴) {StringBuilder [] segments = new StringBuilder [4]; // 여기에서 세그먼트 만 할당합니다. 나머지는 // 주문시 할당됩니다. 세그먼트 [SEG_RAW] = New StringBuilder (); int part = seg_raw; int formatnumber = 0; 부울 개요 = 거짓; int bracestack = 0; maxoffset = -1; for (int i = 0; i <pattern.length (); ++ i) {char ch = pattern.charat (i); if (part == seg_raw) {if (ch == '/' ') {if (i + 1 <pattern.length () && pattern.charat (i + 1) =='/'') {segments [part] .append (ch); // 핸들 복식 ++ i; } else {weote =! Quopote; }} else if (ch == '{'&&! witte) {part = seg_index; if (segments [seg_index] == null) {segments [seg_index] = new StringBuilder (); }} else {segments [part] .append (ch); }} else {if (wifte) {// 부품 세그먼트에 따옴표를 복사합니다 [part] .append (ch); if (ch == '/' ') {wefote = false; }} else {switch (ch) {case ',': if (part <seg_modifier) {if (segments [++ part] == null) {segments [part] = new StringBuilder (); }} else {segments [part] .append (ch); } 부서지다; 사례 '{': ++ 브레이스 테이크; 세그먼트 [part] .Append (ch); 부서지다; case '}': if (bracestack == 0) {part = seg_raw; makeformat (i, formatnumber, segments); 형식 열버 ++; // 다른 세그먼트 세그먼트를 버리십시오 [seg_index] = null; 세그먼트 [seg_type] = null; 세그먼트 [seg_modifier] = null; } else {-Bracestack; 세그먼트 [part] .Append (ch); } 부서지다; CASE '': // SEG_TYPE의 선행 공간 숯을 건너 뜁니다. if (part! = seg_type || segments [seg_type] .length ()> 0) {segments [part] .append (ch); } 부서지다; CASE '/' ': wifte = true; //가 떨어지므로 다른 부분에 따옴표를 유지합니다. 기본값 : 세그먼트 [part] .append (ch); 부서지다; }}}}} if (bracestack == 0 && part! = 0) {maxoffset = -1; 새로운 불법 행위 exception ( "패턴의 타의 추종을 불허하는 버팀대"); } this.pattern = segments [0] .toString (); }위의 코드는 약간 혼란스럽고 약간 이상합니다. 우리는 주로 첫 번째 논리 분기를 살펴 봅니다. 보류중인 각 국제 사본 템플릿 문자열에서 문자를 통과합니다. 캐릭터가 " '"인 경우 다음 캐릭터가 "'"인지 확인하십시오. 그렇다면, 처리 된 StringBuilder에 스플 라이스 " ''를. 그렇지 않다면, 개방부는 사실입니다. 캐릭터가 '{' '이고 호소한이 false 인 경우 부품을 0으로 재설정하고 세그먼트 [seg_index] = null이면 StringBuilder 객체를 재현하십시오. 그렇지 않으면 계속 접합하십시오.
원인 분석 :
해결책:
소스 코드에는 솔루션이 하나뿐입니다. {} 사이의 단일 따옴표는 쌍으로 나타나야합니다. 취급 방법은 다음과 같은 사본을 수정하는 것입니다.
tms.pallet.order.box.qty = 총 팔레트 상자 수량 {0} 수신 상자 수량 {1}과 일치하지 않습니다. 이중 확인하십시오!
카피 라이팅을 직접 수정하는 것은 좋은 솔루션이 아닙니다. Spring이 Applicpattern 메소드를 호출하기 전에 메소드를 다시 작성할 수있는 것이 가장 좋습니다. 불행히도, 봄 3.2.3의 해당 국제 처리 방법은 전적으로 비공개이며, 다시 작성할 수있는 기회를 제공하지는 않습니다.
관련 정보에 컨설팅 한 후 Spring 4.3.2 버전에서는 ResourceBundLemessagesSource 클래스의 GetStringOnull 메소드를 다시 작성하여이를 달성 할 수 있습니다.
장기 솔루션 : 프로젝트에서 스프링 버전을 업그레이드하고 더 많은 새로운 기능을 사용하십시오.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.