Struts 2 의 Date 형식 변환

어제 작은 예 를 마음대로 썼 습 니 다. 프론트 페이지 에 날짜 형식 (yyy - mm - dd) 을 입력 한 텍스트 상자 가 있 습 니 다. action 에 서 는 Date 형식 을 사용 합 니 다.실행 되 었 습 니 다. struts 2 는 형식 변환 을 정확하게 진행 하 였 습 니 다.오늘 다시 실 행 될 때 컨트롤 러 가 잘못 되 었 습 니 다. 대체적으로 String 형식의 set 방법 을 찾 을 수 없습니다.이상 하 다. struts 2 는 Date 의 유형 전환 이 내장 되 어 있 지 않 습 니까? 어제 도 잘 작 동 했 는데 오늘 은 어떻게 된 겁 니까?그리고 찾 아 보 니 이 글 은 내 가 만난 문제 와 똑 같 았 다.
       
http://polaris.blog.51cto.com/1146394/315403
        다음 댓 글 캡 처:
        날짜 유형의 전환 은 웹 개발 에서 거의 만 날 수 있 고 제 가 지금 하고 있 는 프로젝트 도 예외 가 아 닙 니 다.개발 과정 에서 아마 당신 처럼 저 는 날짜 유형 전환 에 대해 특별한 처 리 를 하지 않 았 을 것 입 니 다. 그리고 Struts 2 도 저 를 도와 전환 을 잘 해 주 었 습 니 다.그러나 동료 가 테스트 할 때 '뜬 금 없 는' 문제 가 발생 했다. 자주 사용 하 는 형식의 날짜 유형 yyy - MM - dd 를 입력 하고 배경 에 가서 오 류 를 보고 했다. 대응 하 는 set 방법 인 setEffDate (Ljava. lang. String) 를 찾 을 수 없다.확실히 프로그램 에는 setEffDate (java. util. Date) 라 는 방법 만 있 고 setEffDate (Ljava. lang. String) 라 는 방법 은 없습니다.Ljava. lang. String 에서 알 수 있 듯 이 배경 으로 전 달 된 String 형식 은 Date 형식 으로 바 뀌 지 않 아 오류 가 발생 했 습 니 다.
        처음에는 내 가 UT 를 잘 못 한 줄 알 고 내 컴퓨터 에서 동료의 테스트 를 모 의 한 결과 아무런 문제 가 없 었 다.이상 하 네.자체 분석 을 통 해 IE 브 라 우 저 때 문인 것 같 습 니 다. 동료 테스트 는 IE 를 사 용 했 고 저 는 FireFox 를 사 용 했 기 때 문 입 니 다.그래서 자신의 기계 에서 IE 로 테스트 하고 동료 기계 에서 FireFox 로 테스트 한 결과 두 번 의 테스트 에서 위의 문제 가 발생 하지 않 았 다.문제 의 소 재 를 찾 지 못 했 지만 IE 의 문 제 는 초보 적 으로 긍정 할 수 있 지만 IE 의 문제 가 아 닌 것 같 습 니 다. 제 컴퓨터 에 있 는 IE (버 전 은 동료 와 마찬가지 로 IE6) 는 상기 문제 가 없 기 때 문 입 니 다.이것 은 이상 하 다. 무슨 문제 인지 정말 아무리 생각해 도 이해 가 되 지 않 는 다.
        이때, 나 는 이전에 만 났 던 이해 할 수 없 는 상황 이 생각 났 다. 배경 에서 얻 은 날짜 유형 이 페이지 에 표 시 될 때 위의 상황 과 마찬가지 로 동료의 IE 에서 날짜 표시 형식 은 yyy - MM - ddTHH: mm: ss 이다.T 가 하나 더 생 겼 다 는 것 은 정말 영문 도 모 르 고 동료의 IE 브 라 우 저 에 만 나 타 났 다.yyy - MM - ddTHH: mm: ss 라 는 날짜 형식 이 있 습 니까?그래서 JDK: Simple DateFormat 클래스 에서 이 날짜 형식 을 찾 았 습 니 다. 이 형식 은 '미국 언어 환경 에서 날짜 와 시간의 모델 중 하나' 입 니 다.이런 격식 이 있 었 구나.이것 이 미국 언어 에서 사용 되 는 날짜 형식 이 라 니, Struts 2 는 미국인 이 개발 한 것 으로, 아마도 이것 과 관계 가 있 을 것 이다.그래서 Struts 2 에서 Date 형식 변환 에 대한 소스 코드 를 봅 니 다.
        XWork Basic Converter 클래스 에서
private Object doConvertToDate(Map<String, Object> context, Object value, Class toType) {
	Date result = null;

	if (value instanceof String && value != null && ((String) value).length() > 0) {
		String sa = (String) value;
		Locale locale = getLocale(context);

		DateFormat df = null;
		if (java.sql.Time.class == toType) {
			df = DateFormat.getTimeInstance(DateFormat.MEDIUM, locale);
		} else if (java.sql.Timestamp.class == toType) {
			Date check = null;
			SimpleDateFormat dtfmt = (SimpleDateFormat) DateFormat.getDateTimeInstance(DateFormat.SHORT,
					DateFormat.MEDIUM,
					locale);
			SimpleDateFormat fullfmt = new SimpleDateFormat(dtfmt.toPattern() + MILLISECOND_FORMAT,
					locale);

			SimpleDateFormat dfmt = (SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT,
					locale);

			SimpleDateFormat[] fmts = {fullfmt, dtfmt, dfmt};
			for (SimpleDateFormat fmt : fmts) {
				try {
					check = fmt.parse(sa);
					df = fmt;
					if (check != null) {
						break;
					}
				} catch (ParseException ignore) {
				}
			}
		} else if (java.util.Date.class == toType) {
			Date check = null;
			DateFormat[] dfs = getDateFormats(locale);
			for (DateFormat df1 : dfs) {
				try {
					check = df1.parse(sa);
					df = df1;
					if (check != null) {
						break;
					}
				}
				catch (ParseException ignore) {
				}
			}
		}
		//final fallback for dates without time
		if (df == null) {
			df = DateFormat.getDateInstance(DateFormat.SHORT, locale);
		}
		try {
			df.setLenient(false); // let's use strict parsing (XW-341)
			result = df.parse(sa);
			if (!(Date.class == toType)) {
				try {
					Constructor constructor = toType.getConstructor(new Class[]{long.class});
					return constructor.newInstance(new Object[]{Long.valueOf(result.getTime())});
				} catch (Exception e) {
					throw new XWorkException("Couldn't create class " + toType + " using default (long) constructor", e);
				}
			}
		} catch (ParseException e) {
			throw new XWorkException("Could not parse date", e);
		}
	} else if (Date.class.isAssignableFrom(value.getClass())) {
		result = (Date) value;
	}
	return result;
}

private DateFormat[] getDateFormats(Locale locale) {
	DateFormat dt1 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.LONG, locale);
	DateFormat dt2 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.MEDIUM, locale);
	DateFormat dt3 = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, locale);

	DateFormat d1 = DateFormat.getDateInstance(DateFormat.SHORT, locale);
	DateFormat d2 = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
	DateFormat d3 = DateFormat.getDateInstance(DateFormat.LONG, locale);

	DateFormat rfc3399 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");

	DateFormat[] dfs = {dt1, dt2, dt3, rfc3399, d1, d2, d3}; //added RFC 3339 date format (XW-473)
	return dfs;
}

        그 중에서 도 SHORT, MEDIUM, LONG 은 JDK 의 DateFormat 클래스 에 설명 되 어 있다.
        DateFormat rfc 3399 = new Simple DateFormat ("yyy - MM - dd 'T' HH: mm: ss");Struts 2 하 드 인 코딩 은 이러한 형식 을 사용 한 것 을 알 수 있다.그러나 Struts 2 에 서 는 이 형식 이 마지막 에 놓 여 있 습 니 다. 왜 동료 들 의 IE 브 라 우 저 테스트 에 만 이런 형식 을 사용 합 니까?(디 버 깅 할 때 동시에 IE, 날짜 입력 에서 이런 형식 으로 입력 하면 정말 문제 가 없습니다) 이 설명 은 컴퓨터 에서 앞의 여섯 가지 DateFormat 이 일치 하지 않 습 니 다. DateFormat 에서 SHORT, MEDIUM, LONG 에 대한 설명 을 보면 yyy - MM - dd 와 같은 날짜 유형 은 영어 언어 에서 일치 하지 않 습 니 다. Struts 2 가 날짜 와 일치 하기 때문에Locale 을 사용 한 것 을 보면 동료의 IE 브 라 우 저의 기본 언어 환경 은 영어 입 니 다.확인 해 보 니 과연 중국 어 를 기본 언어 환경 으로 설정 하고 테스트 하 는 것 은 문제 가 없다.마침내 원인 을 알 게 되 었 다.
        개인 적 으로 Struts 2 에서 마지막 날짜 모델 을 미국 표준 으로 쓰 는 것 은 좋 지 않다 고 생각한다.
        이 문제 에 대하 여 우 리 는 고객 에 게 중국 어 를 기본 브 라 우 저의 언어 환경 으로 설정 하 라 고 요구 할 수 없습니다.따라서 Date 형식의 변환 에 대해 서 는 컨버터 를 스스로 정의 할 수 있 습 니 다.다음은 [url] 에서http://www.iteye.com/wiki/struts2/1365-passing-parameters-in-struts2 [/ url] 의 유형 변환기 정의 (국제 화 환경 에 적합 하지 않 음) 가 필요 하 다 면 자신의 변환 기 를 정의 할 수 있 습 니 다.
public class DateConverter extends DefaultTypeConverter {

        private static final Logger logger = Logger.getLogger(DateConverter.class);

        private static final String DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss";

        private static final String DATE_PATTERN = "yyyy-MM-dd";
        
        private static final String MONTH_PATTERN = "yyyy-MM";

        /**
         * Convert value between types
         */
        @SuppressWarnings("unchecked")
        public Object convertValue(Map ognlContext, Object value, Class toType) {
                Object result = null;
                if (toType == Date.class) {
                        result = doConvertToDate(value);
                } else if (toType == String.class) {
                        result = doConvertToString(value);
                }
                return result;
        }

        /**
         * Convert String to Date
         *
         * @param value
         * @return
         */
        private Date doConvertToDate(Object value) {
                Date result = null;

                if (value instanceof String) {
                        result = DateUtils.parseDate((String) value, new String[] { DATE_PATTERN, DATETIME_PATTERN, MONTH_PATTERN });

                        // all patterns failed, try a milliseconds constructor
                        if (result == null && StringUtils.isNotEmpty((String)value)) {

                                try {
                                        result = new Date(new Long((String) value).longValue());
                                } catch (Exception e) {
                                        logger.error("Converting from milliseconds to Date fails!");
                                        e.printStackTrace();
                                }

                        }

                } else if (value instanceof Object[]) {
                        // let's try to convert the first element only
                        Object[] array = (Object[]) value;

                        if ((array != null) && (array.length >= 1)) {
                                value = array[0];
                                result = doConvertToDate(value);
                        }

                } else if (Date.class.isAssignableFrom(value.getClass())) {
                        result = (Date) value;
                }
                return result;
        }

        /**
         * Convert Date to String
         *
         * @param value
         * @return
         */
        private String doConvertToString(Object value) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATETIME_PATTERN);
                String result = null;
                if (value instanceof Date) {
                        result = simpleDateFormat.format(value);
                }
                return result;
        }
}

        이 변환 기 를 전역 으로 등록 할 수 있 습 니 다: src (eclipse) 에서 xwork - conversion. properties 파일 을 만 들 수 있 습 니 다. 내용 은 자바 util. Date = 형식 변환기 의 전체 한정 클래스 입 니 다.
        몇 마디 만 더 하 겠 습 니 다. 제 시스템 은 영어 입 니 다. chrome 브 라 우 저 로 테스트 했 습 니 다.문 제 는 하루 동안 이 시스템 환경 이 변 한 적 이 없 는데 왜 지난번 에 통 과 했 는 지, 다음 에는 통 하지 않 는 지........................................................

좋은 웹페이지 즐겨찾기