我为用户创建了一些表单:
<form:form action="${pageContext.request.contextPath}/user/create" method="post" modelAttribute="userCreateForm" autocomplete="off">
<table class="b-table table table-striped">
<tbody>
<tr>
<td><spring:message code="UI.Labels.User.FirstName"/></td>
<td>
<form:input type="text" path="firstName" cssClass="form-control"/>
</td>
</tr>
<tr>
<td><spring:message code="UI.Labels.User.LastName"/></td>
<td>
<form:input type="text" path="lastName" cssClass="form-control"/>
</td>
</tr>
<tr>
<td><spring:message code="UI.Labels.User.Role"/></td>
<td>
<form:select path="userRole" cssClass="form-control">
<form:options items="${roles}"/>
</form:select>
</td>
</tr>
<tr>
<td><spring:message code="UI.Labels.User.Email"/></td>
<td>
<form:input type="text" path="email" cssClass="form-control" autocomplete="off"/><span><form:errors path="email" cssClass="error"/></span>
</td>
</tr>
<tr>
<td><spring:message code="UI.Labels.User.Password"/></td>
<td>
<form:input type="password" path="password" cssClass="form-control" autocomplete="off"/><span></span>
</td>
</tr>
<tr>
<td><spring:message code="UI.Labels.User.Pictire"/></td>
<td>
<input type="file" name="file" cssClass="form-control"/><span></span>
</td>
</tr>
</tbody>
</table>
<button class="btn btn-primary" type="submit" name="submit">
<spring:message code="UI.Labels.User.Submit"/>
</button>
</form:form>
控制器:
@RequestMapping("/create")
public String createPage(Model model, Principal principal, Locale locale) {
final User loggedUser = getLoggedUser();
User userCreateForm = new User();
model.addAttribute("userCreateForm", userCreateForm);
//model.addAttribute("roles", Utils.localizedRoles(loggedUser.getUserRole(), messageSource, locale));
model.addAttribute("roles", systemRoleService.findAll());
return "user/create";
}
@RequestMapping(value = "/create", method = RequestMethod.POST)
public String create(
@ModelAttribute User userForm,
BindingResult bindingResult,
Model model,
Locale locale,
RedirectAttributes redirectAttributes) {
if(bindingResult.hasErrors()) {
return "user/create";
}
try {
userForm.setPassword(Utils.bcrypt(userForm.getPassword()));
userForm.setLogin(userForm.getEmail());
userService.create(userForm);
redirectAttributes.addFlashAttribute("success", messageSource.getMessage("UI.Messages.User.CreatedSuccess", null, locale));
} catch (ResourceException ue) {
final User loggedUser = getLoggedUser();
final List<String> failures = new ArrayList<>();
for(String m : ue.getMessages()) failures.add( messageSource.getMessage(m, null, locale) );
model.addAttribute("failures", failures);
model.addAttribute("userCreateForm", userForm);
model.addAttribute("roles", Utils.localizedRoles(loggedUser.getUserRole(), messageSource, locale));
return "user/create";
}
return "redirect:/";
}
如果我没有选择任何角色 - 它工作正常,但保存没有角色的用户。 当我在.jsp中选择userRole并按“保存”时 - 我有一个错误:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'userCreateForm' available as request attribute
请帮我解决这个问题。 你能告诉我出了什么问题吗?
如果我选择了一个角色,那么在@ModelAttribute中我得到的是SystemRole对象而不是User ....为什么?
现在我收到了一个新错误:
Field error in object 'userCreateForm' on field 'userRole': rejected value [6]; codes [typeMismatch.userCreateForm.userRole,typeMismatch.userRole,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [userCreateForm.userRole,userRole]; arguments []; default message [userRole]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.List' for property 'userRole'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [ru.test.jpa.SystemRole] for property 'userRole[0]': no matching editors or conversion strategy found]
在User对象中,提交的'userRole' - 是List。 如何从jsp中获取所选角色的列表?
我添加了转换器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;
import ru.test.jpa.SystemRole;
@Component("userRoleConverter")
public class UserRoleConverter implements Converter<String, SystemRole> {
@Autowired
private ResourceService<SystemRole> systemRoleService;
@Override
public SystemRole convert(String id) {
return systemRoleService.findOne(Long.valueOf(id));
}
}
并将其注册在sprint-context.xml
中<beans:bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<beans:property name="converters">
<beans:ref bean="userRoleConverter"/>
</beans:property>
</beans:bean>
我仍然得到同样的错误。 有什么问题?
非常感谢。
答案 0 :(得分:0)
错误消息中最相关的部分是:Cannot convert value of type [java.lang.String] to required type [ru.test.jpa.SystemRole] for property 'userRole[0]'
。
您没有显示User
类,但由于错误,我认为userRole
是SystemRole
的集合或数组。您可以使用包装类作为表单对象,该表单对象具有接受字符串集合的setter并生成角色,如:
class UserWrapper {
class User user = new User();
// delegates for setters and getters omitted for breivety
public void setStrUserRole(List<String> strRole) {
role = new List<SystemRole>();
for (String str: strRole) {
// build role r form its String representation
role.add(r);
}
}
}
或者您可以创建Converter<String, SystemRole>
并将其注册到Spring使用的DefaultFormattingConversionService
。
如果使用XML配置,则可以通过以下方式注册新转换器:
<bean class="org.springframework.format.support.FormattingConversionServiceFactoryBean"
id="conversionService"/>
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"
p:targetObject-ref="conversionService" p:targetMethod="addConverter">
<property name="arguments">
<list>
<value type="java.lang.Class">java.lang.String</value>
<value type="java.lang.Class">ru.test.jpa.SystemRole</value>
<ref bean="userRoleConverter"/>
</list>
</property>
</bean>
因为您只想添加一个新的转换器,而不是替换整个默认的Spring转换器。