enter code here
我有一个控制器,下面两个网址映射为名为Member的业务对象的GET和POST。
控制器:
@RequestMapping(value = "/usr/updateMember", method = RequestMethod.GET)
public ModelAndView findForEdit(@RequestParam("id") Integer id) {
ModelAndView modelAndView = new ModelAndView("registration");
try {
List<City> cities = getGenericDao().getAllItems(City.class);
List<Chapter> chapters = getGenericDao().getAllItems(Chapter.class);
modelAndView.getModel().put("cities", cities);
modelAndView.getModel().put("chapters", chapters);
Member member = getGenericDao().getItem(Member.class, id);
modelAndView.getModel().put("edit", true);
modelAndView.getModel().put("loggedinuser", getPrincipal());
modelAndView.getModel().put("roles", userRoleService.findAll());
modelAndView.getModel().put("member", member);
} catch (Exception e) {
System.out.println(e.getMessage());
}
return modelAndView;
}
@RequestMapping(value = "/usr/updateMember", method = RequestMethod.POST)
public String update(@ModelAttribute("member") Member member, BindingResult result, SessionStatus status) {
getGenericDao().update(member);
status.setComplete();
return "redirect:/list.do";
}
我的观点如下:
<form:form method="POST" modelAttribute="member"
class="horizForm">
<div class="row">
<div class="form-group col-md-">
<label class="col-md-3" for="name">Member
Name</label>
<div class="col-md">
<form:input type="text" path="name" id="name"
class="form-control input-sm" />
<div class="has-error">
<form:errors path="name" class="help" />
</div>
</div>
</div>
</div>
...
<div class="row">
<div class="form-group col-md-12">
<label class="col-md-3" for="userRoles">Roles</label>
<div class="col-md">
<form:select path="userRoles" items="${roles}" multiple="true"
itemValue="memberId" itemLabel="role"
class="form-control input-sm" />
<div class="has-error">
<form:errors path="userRoles" class="help" />
</div>
</div>
</div>
</div>
<div class="row">
<div class="form-group col-md-">
<label class="col-md-3 control-labl" for="chapter">Chapter</label>
<div class="col-md-7">
<%-- <form:select path="chapter.id" items="${chapters}" itemValue="id"
itemLabel="name" class="form-control input-sm"> --%>
<%-- <option value="-1">Select a Chapter</option>
<c:forEach var="chp" items="${chapters}">
<option value="${chp.id}">${chp.name}</option>
</c:forEach> --%>
<%-- </form:select> --%>
<form:select path="chapter" class="form-control input-sm">
<!-- <option value="-1">Select a Chapter</option> -->
<c:forEach var="chp" items="${chapters}">
<option value="${chp}">${chp.name}</option>
</c:forEach>
</form:select>
<div class="has-error">
<%-- <form:errors path="chapter.id" class="help-inline" /> --%>
<form:errors path="chapter" class="help-inline" />
</div>
</div>
</div>
</div>
GET按预期工作,View填充了String,List和Chapter类型对象的预期值。
当我尝试通过POST更新成员时,它不会获取绑定到List和Chapter对象的值,而BindingResult的值低于值。
org.springframework.validation.BeanPropertyBindingResult: 3 errors
Field error in object 'member' on field 'chapter': rejected value [Chapter [chapterId=1, chapterName=SUPER]]; codes [typeMismatch.member.chapter,typeMismatch.chapter,typeMismatch.com.codex.survey.beans.Chapter,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [member.chapter,chapter]; arguments []; default message [chapter]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'com.codex.survey.beans.Chapter' for property 'chapter'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.codex.survey.beans.Chapter] for property 'chapter': no matching editors or conversion strategy found]
Field error in object 'member' on field 'userRoles': rejected value [2]; codes [typeMismatch.member.userRoles,typeMismatch.userRoles,typeMismatch.java.util.List,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [member.userRoles,userRoles]; arguments []; default message [userRoles]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'java.util.List' for property 'userRoles'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.codex.survey.beans.UserRole] for property 'userRoles[0]': no matching editors or conversion strategy found]
我无法通过视图来确定这里出了什么问题,请帮我解决这个问题。
感谢您的期待。
答案 0 :(得分:0)
与有状态的,基于组件的框架(例如JSF)不同,Spring MVC无法自动将原始HTTP参数转换为相应的对象类型。
因此,您需要注册一个转换器来处理它并将其注册到Spring上下文中。有多种方法可以做到这一点,但一种实现方式如下:
@Component
public class StringToChapterConverter implements Converter<String, Chapter> {
@Autowired
private ChaperService service;
/**
*chapterId is the HTTP post param passed in by the framework
*/
public Chapter convert(String chapterId) {
return service.findChapter(Integer.parseInt(chapterId));
}
}
如何注册这取决于您的配置。但是假设Java代码配置:
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "..." })
public class MvcConfiguration extends WebMvcConfigurerAdapter{
//other configuration
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
formatterRegistry.addConverter(getChapterConverter());
}
@Bean
public StringToChapterConverter getChapterConverter(){
return new StringToChapterConverter();
}
}
所以,现在有了上面的命令,当一个请求被绑定到Chapter对象时,框架将查看是否已为Chapter类型定义了合适的转换器,然后调用相应的convert(String source)这使您可以从数据库或任何地方返回实例。
进一步了解: