【发布时间】:2014-12-10 12:48:08
【问题描述】:
我对 Spring 中的格式化程序有疑问。
我的选择框有一个格式化程序,例如:
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));
}
}
在百里香中是这样的:
<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>
这很简单,因为我只需要一个值(id)并且我将使用选择框。
但是如果我需要两个值怎么办?
建议我有电子邮件,我需要 id 和值(邮件地址)。我可以为电子邮件构建一个格式化程序,但我没有机会同时传输电子邮件和 ID。
在打印方法中我可以这样:
@Override
public String print(Email email, Locale locale) {
return email.getId() + email.getEmail();
}
在百里香中:
<input id="email" type="text" class="form-control" th:field="*{{person.email}}" th:placeholder="#{login.email}" />
但是有了这个用户可以看到id。
如果我使用“标准”Spring 方式进行绑定,则会出现以下异常(这就是我使用格式化程序的原因):
{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 [com.sample.persistence.user.model.Email@0];
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
'com.sample.persistence.user.model.Email@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]],
message=Validation failed for object='person'. Error count: 1, path=/manageUsers/Ab-Soul/edit}
欢迎提出任何建议。
提前致谢。
1.编辑:
控制器方法
@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;
}
场景中,'admin' 获取所有当前用户的列表,如果他点击表格,requestmapping-method 将使用他点击的用户名被调用。
电子邮件类:
@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 [com.sample.persistence.user.model.Email@0];
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 'com.sample.persistence.user.model.Email@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);
}
【问题讨论】:
-
“标准”Spring 方式是最好的方式,能否请您提供您的电子邮件对象详细信息、控制器和 html 页面?您是否仅在执行编辑或创建新用户时遇到此问题?
-
@PatrickLC 抱歉回复晚了,但我家里没有数据。如果我创建一个新用户,我有另一个结构,通过注册有以下结构:Person -> Child -> email and in edit(发生错误的地方):Person -> List
-> email -
如果您尝试编辑一个只有一个孩子的人并且关联的电子邮件工作正常?
-
不,然后我得到错误。如果我编辑来自该人的电子邮件,它将适用于该人。我混淆的一点是,人和孩子的电子邮件对象是一样的。
-
好消息! :) 我认为这是一个完美的解决方案,有人也有类似的复杂对象绑定问题(仅供参考:stackoverflow.com/questions/16895406/…)
标签: java spring spring-boot thymeleaf formatter