2014-12-10 6 views
0

스프링 포매터에 대한 질문이 있습니다. 나는 단지 하나 개의 값 (ID를) 필요로하기 때문에,입력 필드 용 스프링 포매터

<select class="form-control" name="sportTypeId" th:field="*{person.sport.sportType}"> 
    <option th:each="spoType : ${allSportTypes}" th:value="${spoType.typeId}" th:selected="${spoType.typeId == person.sport.sportType}" th:text="#{${'login.sport.sportType.' + spo.typeId}}" >Sporttype</option> 
</select> 

은 그게 전부가 쉽고 :

public class SportTypeFormatter implements Formatter<SportType> { 

    @Autowired 
    private SportTypeRepository sportTypeRepository; 

    @Override 
    public String print(SportType sportType, Locale locale) { 
     return String.valueOf(sportType.getTypeId()); 
    } 

    @Override 
    public SportType parse(String sportTypeId, Locale locale) throws ParseException { 
     return sportTypeRepository.findSportTypeByTypeId(Long.valueOf(sportTypeId)); 
    } 
} 

이 같은 thymeleaf 뭔가 :

나는 예를 들어, 내 선택 상자에 대한 포맷터를 나는 select-box로 갈거야.

하지만 두 값이 필요한 경우 어떻게해야합니까?

제안 이메일을 보내려면 ID와 값 (메일 주소)이 필요합니다. 전자 메일 용 포맷터를 만들 수 있지만 이메일과 ID를 동시에 전송할 수는 없습니다. 인쇄 방법에서

내가 그런 걸 할 수

@Override 
public String print(Email email, Locale locale) { 
    return email.getId() + email.getEmail(); 
} 

thymeleaf에서 :

<input id="email" type="text" class="form-control" th:field="*{{person.email}}" th:placeholder="#{login.email}" /> 

그러나이 사용자와의

는 ID를 볼 수 있습니다.

만약 내가 할 나는 다음과 같은 예외가 "표준"봄 길 (내가 포맷터를 사용하는 이유를 먹으 렴) 바인딩 :

{timestamp=Wed Dec 10 11:14:47 CET 2014, status=400, error=Bad Request, exception=org.springframework.validation.BindException, 
errors=[Field error in object 'person' on field 'email': rejected value [[email protected]]; 
codes [typeMismatch.person.email,typeMismatch.person.institutionEmployees.email, 
     typeMismatch.email,typeMismatch.email, 
     typeMismatch.email,typeMismatch.com.sample.persistence.user.model.Email,typeMismatch]; 
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: 
      codes [person.email,email]; 
      arguments []; 
      default message [email]]; 
      default message [Failed to convert property value of type 'com.sample.persistence.user.model.Email' 
          to required type 'com.sample.persistence.user.model.Email' 
          for property 'email'; 
          nested exception is org.springframework.core.convert.ConversionFailedException: 
          Failed to convert from type com.sample.persistence.user.model.Email 
          to type @javax.persistence.OneToOne @javax.persistence.JoinColumn @com.google.gson.annotations.Expose 
            com.sample.persistence.user.model.Email for value 
            '[email protected]'; 
          nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: 
            Provided id of the wrong type for class com.sample.persistence.user.model.Email. 
            Expected: class java.lang.Long, got class java.lang.String; 
          nested exception is java.lang.IllegalArgumentException: 
            Provided id of the wrong type for class com.sample.persistence.user.model.Email. 
            Expected: class java.lang.Long, got class java.lang.String]], 
            message=Validation failed for object='person'. Error count: 1, path=/manageUsers/Ab-Soul/edit} 

어떤 제안을 환영합니다.

미리 감사드립니다.

1. 편집 : 그는 테이블 requestmapping-방법에 클릭 한 경우

@RequestMapping(value = "/{login}/edit", method = RequestMethod.GET) 
public ModelAndView editUserByLogin(@PathVariable("login") final String login) { 
    final User currentUser = UserRepository.findPersonByLogin(login); 

    ModelAndView mav = new ModelAndView(URL_EDIT_USER); 
    mav.addObject(MODEL_USER, currentUser); 

    return mav; 
} 

시나리오가의 '관리자가'현재의 모든 사용자의 목록을

감사관-방법 그가 클릭 한 사용자의 이름으로 호출됩니다.

이메일 클래스 :

@Entity(name="Email") 
public class Email implements Serializable 
{ 
    private static final long serialVersionUID = 6891079722082340011L; 

    @Id() 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    @Expose 
    protected Long emailId; 
    @Expose 
    protected String value; 

    //getter/setter 

    @Override 
    public boolean equals(Object obj) 
    { 
     if(obj instanceof Email){ 
      return value.equals(((Email) obj).getValue()); 
     } 
     return false; 
    } 

    @Override 
    public int hashCode() 
    { 
     return value.hashCode(); 
    } 
} 

2. 편집 : 이제

내가 아이의 이메일 필드를 변경해야이 emailChild하는

org.springframework.validation.BeanPropertyBindingResult: 1 errors 
Field error in object 'person' on field 'child[0].emailChild': 
rejected value [[email protected]]; 
codes [typeMismatch.person.child[0].emailChild, 
     typeMismatch.person.child.emailChild, 
     typeMismatch.child[0].emailChild, 
     typeMismatch.child.emailChild, 
     typeMismatch.emailChild, 
     typeMismatch.com.sample.persistence.user.model.Email,typeMismatch]; 
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: 
    codes [person.child[0].emailChild,child[0].emailChild]; 
arguments []; 
default message [child[0].emailChild]]; 
default message [Failed to convert property value of type 'com.sample.persistence.user.model.Email' to required type 'com.sample.persistence.user.model.Email' 
     for property 'child[0].emailChild'; 
nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type com.sample.persistence.user.model.Email 
to type @javax.persistence.OneToOne @javax.persistence.JoinColumn @com.google.gson.annotations.Expose com.sample.persistence.user.model.Email 
for value '[email protected]0'; 
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Provided id of the wrong type for class com.sample.persistence.user.model.Email. Expected: class java.lang.Long, got class java.lang.String; 
nested exception is java.lang.IllegalArgumentException: Provided id of the wrong type for class com.sample.persistence.user.model.Email. Expected: class java.lang.Long, got class java.lang.String] 

3. 편집 :

게시물에 대한 컨트롤러 메소드 추가 :

@RequestMapping(value = "/{login}/edit", method = RequestMethod.POST) 
public ModelAndView updateUser(@PathVariable("login") final String login, @ModelAttribute(MODEL_USER) final Person person, BindingResult bindingResult, final Model model) { 
    Person repositoryPerson = personRepository.findPersonByLogin(login); 

    repositoryPerson = repositoryPerson.updateWith(person); 
    manageUserService.updatePerson(repositoryPerson); 

    model.asMap().clear(); 
    return new ModelAndView("redirect:" + URL_USERS_OVERVIEW, MODEL, model); 
} 
+0

「표준」봄 방법 : 바인딩 문제는 그 다음 "complexer"(두 개 이상의 관련 분야) 객체에 의해 발생하는 경우

그러나

, 내가 생각하는, 당신은 PatrickLC 제안 솔루션을 더 흰색 이동 가장 좋은 방법은 전자 메일 개체 세부 정보, 컨트롤러 및 html 페이지를 포함시킬 수 있습니까? 편집을 수행 할 때만 또는 새 사용자를 만들 때이 문제가 있습니까? –

+0

@PatrickLC 늦은 답변을 드려 죄송합니다. 데이터는 집에 없습니다. Person -> Child -> 이메일 및 편집 (오류가 발생하는 곳) : Person -> List -> 이메일 –

+0

시도 할 경우 다른 구조가있는 새 사용자를 만들면 등록에 의해 다음과 같은 구조가 있습니다. 오직 하나의 하위와 관련 이메일을 가진 사람을 편집 잘 작동합니까? –

답변

0

나는 내 자신의 질문에 대답했습니다.

우리는 등록 프로세스가 잘 작동

  • , 그것은 결합 것을 기억해야 잘

만 문제는 편집 과정에서 발생하는, 그래서는 DB에 유효한 이메일-개체가 유효한 Child-Object로 바인딩하고 이는 유효한 User-Object와 바인딩됩니다.

나는 다음과 같은 implemenatation와 EmailFormatter을 구축하기로 결정했습니다 :이와

public class EmailFormatter implements Formatter<Email> { 

    @Override 
    public String print(Email email, Locale locale) { 
     return email.getValue(); 
    } 

    @Override 
    public Email parse(String mailAddress, Locale locale) throws ParseException { 
     return new Email(mailAddress); 
    } 

} 

, 내 아이-인스턴스 (아이디없이) 새로운 이메일-객체 얻을. 이제 유효한 하위 개체에 유효한 전자 메일 개체가 있습니다. 포스트 방법에보세요 :

@RequestMapping(value = "/{login}/edit", method = RequestMethod.POST) 
public ModelAndView updateUser(@PathVariable("login") final String login, @ModelAttribute(MODEL_USER) final Person person, BindingResult bindingResult, final Model model) { 
    Person repositoryPerson = personRepository.findPersonByLogin(login); 

    repositoryPerson = repositoryPerson.updateWith(person); 
    manageUserService.updatePerson(repositoryPerson); 

    model.asMap().clear(); 
    return new ModelAndView("redirect:" + URL_USERS_OVERVIEW, MODEL, model); 
} 

를 i는 사용자의 로그인 이름이이 때, 나는 dB에서 "이전"(유효) 사용자가 객체를 가져옵니다. "병합"메서드를 작성했습니다. "이전"사용자 개체에 수정 된 사용자 개체를 제공합니다.

여기에 내가 ID로 기존 이메일 개체를 얻을 그냥 같이 이메일-ADRESS을 설정할 수 있습니다 :이 솔루션 볼이 후

this.emailChild.setValue(modifiedChild.getemailChild().getValue()); 

을, 나는 그게 정말 간단하게 알 수 있습니다.

@InitBinder 
public void setAllowedFields(WebDataBinder dataBinder) { 
    dataBinder.setDisallowedFields("emailId"); 
}