在jsp

时间:2016-08-28 12:34:33

标签: spring-mvc jstl

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类型对象的预期值。

GET Method working fine

当我尝试通过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]

我无法通过视图来确定这里出了什么问题,请帮我解决这个问题。

感谢您的期待。

1 个答案:

答案 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)这使您可以从数据库或任何地方返回实例。

进一步了解:

http://docs.spring.io/spring/docs/current/spring-framework-reference/html/validation.html#core-convert