2011-01-18 3 views
5

저는 Float 값을 바인딩하기 위해 CustomNumberEditorEditor 편집기를 사용하고 있습니다. 값이 숫자가 아닌 경우 가끔 값을 구문 분석하여 오류가 반환되지 않는다고 실험했습니다.Spring CustomNumberEditor가 숫자가 아닌 숫자를 파싱합니다.

  • 수 = 10 ...... 다음 = 수가 10이고
  • 번호 = 10A는 ...... 그 수가 10 인 오류가 없다 및
  • 수가 오류를 없다 10a25 ...... 다음 수는 10이고 수는

은 그래서 에디터가 값을 구문 분석하는 것 유효하지 않기 때문에

  • 수가 ...... 오류 = 오류가 없습니다 할 수있을 때까지 나머지는 생략하십시오. 유효성 검사가 엄격하도록 (예 : 10a 또는 10a25와 같은 숫자가 오류가 발생하도록)이 편집기를 구성하는 방법이 있습니까? 아니면 사용자 정의 구현을 빌드해야합니까? CustomDateEditor/DateFormat에서 lenient를 false로 설정하는 것과 비슷하게 날짜를 가장 가능성있는 것으로 파싱 할 수 없습니다.

    내가 편집기를 등록하는 방법은 다음과 같습니다

    @InitBinder 
    public void initBinder(WebDataBinder binder){ 
        NumberFormat numberFormat = NumberFormat.getInstance(); 
        numberFormat.setGroupingUsed(false); 
        binder.registerCustomEditor(Float.class, new CustomNumberEditor(Float.class, numberFormat, true)); 
    } 
    

    감사합니다.

  • 답변

    4

    첫 번째 잘못된 문자로 입력 문자열을 구문 분석하는 NumberFormat 클래스에 의존하므로 NumberFormat 클래스를 확장해야합니다.

    언뜻 당신이 아 파크의 NumberFormat를 할 수 없습니다

    public class StrictFloatNumberFormat extends NumberFormat { 
    
        private void validate(in) throws ParseException{ 
        try { 
         new Float(in); 
        } 
        catch (NumberFormatException nfe) { 
         throw new ParseException(nfe.getMessage(), 0);  
        } 
    
    
        public Number parse(String in) throws ParseException { 
        validate(in); 
        super.parse(in); 
        } 
        ..... //any other methods 
    } 
    
    +0

    감사합니다. 그러나 사용자 지정 구현을 만들었다면 CustomNumberEditor 클래스를 확장하고 setAsText 메서드 검사를 재정의 할 수 있다고 생각합니다. 값이 숫자 일 경우 super.setAsText – Javi

    7

    될 것이다.

    문서는이 사실에 대해 분명하다

    /** 
    * Parses text from the beginning of the given string to produce a number. 
    * The method may not use the entire text of the given string. 
    * <p> 
    * See the {@link #parse(String, ParsePosition)} method for more information 
    * on number parsing. 
    * 
    * @param source A <code>String</code> whose beginning should be parsed. 
    * @return A <code>Number</code> parsed from the string. 
    * @exception ParseException if the beginning of the specified string 
    *   cannot be parsed. 
    */ 
    public Number parse(String source) throws ParseException { 
    

    이 API acceept 그것도 당신이 원하는 것을하는 파서를 작성하고하는 NumberFormat 인터페이스를 구현하는 경우에도 유효하지 않은 것

    . 즉, 대신 자신의 속성 편집기를 구현해야합니다.

    /* untested */ 
    public class StrictNumberPropertyEditor extends PropertyEditorSupport { 
    
        @Override 
        public void setAsText(String text) throws IllegalArgumentException { 
         super.setValue(Float.parseFloat(text)); 
        } 
    
        @Override 
        public String getAsText() { 
         return ((Number)this.getValue()).toString(); 
        }  
    } 
    
    3

    나는 가장 우아한 방법은 다음과 같이 NumberFormat.parse(String,ParsePosition), 뭔가를 사용하는 것입니다 생각 :

    public class MyNumberEditor extends PropertyEditorSupport { 
        private NumberFormat f; 
        public MyNumberEditor(NumberFormat f) { 
         this.f = f; 
        } 
    
        public void setAsText(String s) throws IllegalArgumentException { 
         String t = s.trim(); 
         try { 
          ParsePosition pp = new ParsePosition(0); 
          Number n = f.parse(t, pp); 
          if (pp.getIndex() != t.length()) throw new IllegalArgumentException(); 
          setValue((Float) n.floatValue()); 
         } catch (ParseException ex) { 
          throw new IllegalArgumentException(ex); 
         } 
        } 
    
        ... 
    } 
    
    관련 문제