Spring 4 MVC在修改post请求之前更新实体

控制器:

@PreAuthorize("@securityService.isAdminForSurvey(principal.user, #survey)")
@RequestMapping(value = "/service-management/surveys/{survey}/edit", method = RequestMethod.GET)
public String editSurvey(@PathVariable Survey survey, Model model) {

    model.addAttribute("survey", survey);


@PreAuthorize("@securityService.isAdminForSurvey(principal.user, #survey)")
@RequestMapping(value = "/service-management/surveys/{survey}/edit", method = RequestMethod.POST)
public String editSurvey(@ModelAttribute("survey") Survey survey, SessionStatus sessionStatus) {
        surveyService.update(survey);

转换器:

@Component
public class SurveyConverter implements Converter<String, Survey> {
    @Autowired
    private SurveyService surveyService;
    @Override
    public Survey convert(String hash){
        try {
            return surveyService.getSurveyByHash(hash);
        }catch(NumberFormatException e){
            return null;
    }

}

}

当我使用弹簧表单中的修改数据发送发布请求时,不知何故,在调用安全服务之前对象会被更新。 即使调用保存方法之前,Repository也会返回已更新的调查实体和表单中的值。 甚至有可能吗?

显示安全服务方法在这里触发的编辑器是一些带有方法调用队列的日志:

2016-04-12 15:08:44.282  INFO 12496 --- [nio-8080-exec-8] ....service.SurveyServiceImpl       : [.....service.SurveyServiceImpl.getSurveyByHash(SurveyServiceImpl.java:87)]
2016-04-12 15:08:44.290  INFO 12496 --- [nio-8080-exec-8] ....security.SecurityService    : [.....security.SecurityService.isAdminForSurvey(SecurityService.java:38)]
2016-04-12 15:08:44.295  INFO 12496 --- [nio-8080-exec-8] ....controller.SurveyController     : [....controller.SurveyController.editSurvey(SurveyController.java:362)]

问题调查导致下一个结论:

  • @PreAuthorize #survey参数被误用,因为它的目的是模型属性,而不是路径变量预期。
  • 因为@PathVariable@ModelAttribute具有相同的名称,所以jsp页面中的表单在春季自动绑定到调查对象。
  • 解决方案是为@PathVariable@ModelAttribute使用不同的名称。 在这种情况下,转换器的行为正确 - 从url转换值,并且@ModelAttribute对象包含表单中的值。 有人能够点亮为什么Spring会这样吗? 在Spring 3上观察到类似的行为。

    与SQL相同的日志

    2016-04-13 00:41:18.636  INFO 4445 --- [nio-8080-exec-6] .....service.SurveyServiceImpl       : [.....service.SurveyServiceImpl.getSurveyByHash(SurveyServiceImpl.java:87)]
    Hibernate: 
    select
        survey0_.id as id1_11_,
        survey0_.hash as hash19_11_,
        survey0_.version as version48_11_ 
    from
        survey survey0_ 
    where
        survey0_.hash=?
    Hibernate: 
    select
        adminsurve0_.id as id1_0_0_,
        adminsurve0_.enable_edit as enable_e2_0_0_,
        adminsurve0_.survey_id as survey_71_0_0_ 
    from
        admin_survey_permissions adminsurve0_ 
    where
        adminsurve0_.survey_id=?
    2016-04-13 00:41:18.646  INFO 4445 --- [nio-8080-exec-6] ....security.PtspSecurityService    : [.....security.PtspSecurityService.isAdminForSurvey(PtspSecurityService.java:38)]
    Hibernate: 
    select
        'true' as col_0_0_ 
    from
        users user0_ 
    where
        user0_.id=? 
        and (
            user0_.is_super_admin=true 
            or user0_.is_admin=true 
        )
    2016-04-13 00:41:18.653  INFO 4445 --- [nio-8080-exec-6] .....controller.SurveyController     : [.....controller.SurveyController.editSurvey(SurveyController.java:362)]
    Hibernate: 
    select
        adminsurve0_.id as id1_0_,
        adminsurve0_.enable_edit as enable_e2_0_,
        adminsurve0_.survey_id as survey_71_0_ 
    from
        admin_survey_permissions adminsurve0_ 
    left outer join
        survey survey1_ 
            on adminsurve0_.survey_id=survey1_.id 
    where
        survey1_.id=?
    

    注意:

    sql输出被缩短了,因为对象包含很多带有一些数据的字段。

    链接地址: http://www.djcxy.com/p/92557.html

    上一篇: Spring 4 MVC updates entity before modifying post request

    下一篇: How does <form> action works?