使用MethodValidationPostProcessor进行Spring验证

时间:2014-09-22 22:37:13

标签: java spring validation

我正在尝试使用Spring的MethodValidationPostProcessor进行服务层验证。我曾计划创建一个通用服务接口,并让控制器按类型注入正确的服务:

@Controller
@RequestMapping("/items")
public class ItemController {

  @Inject
  // inject a service for the domain type i am controller for
  private Service<Item> service;

  @RequestMapping(method = RequestMethod.POST, produces="application/json")
  public @ResponseBody Item create(@RequestBody Item item){
    return this.service.execute(item);
  }
}

我有一个通用的服务定义和一个简单的实现:

public interface Service<T> {
  public T execute(@Valid T item);
}

// example implementation:
@Named
@Validated
public class ItemService implements Service<Item>{

  @Override
  public Item execute(@Valid Item item) {
    return item;
  }
}

然后设置我的应用程序以包含Springs MethodValidationPostProcessor来处理@Validated bean:

@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
    public static void main( String[] args ){
        SpringApplication application = new SpringApplication(Application.class);
        application.run(args);
    }

    @Bean
    public MethodValidationPostProcessor getMethodValidationPostProcessor(){
        MethodValidationPostProcessor processor = new MethodValidationPostProcessor();
        processor.setValidator(this.validator());
        return processor;
    }

    @Bean
    public LocalValidatorFactoryBean validator(){
        return new LocalValidatorFactoryBean();
    }
}

此设置产生以下异常:

HV000162: The validated type org.commons.test.validation.ItemService does not specify the constructor/method: public abstract java.lang.Object org.commons.test.validation.Service.execute(java.lang.Object)

我很确定这是由于传递给验证器的代理,但我似乎无法找到它。我确信这必须有效(因为我确信春天的人已经想到了这一点)而我只是错过了一些东西......任何帮助都会非常感激。

更新

所以我发现如果Service<T>是一个抽象类而不是一个接口,那么一切都有效。同样,如果我将Service<T>作为接口,只需在方法中添加另一个参数,即:execute(String dummy, @Valid T value)这也会导致验证按预期工作。我开始认为这是一个错误......

1 个答案:

答案 0 :(得分:0)

@Valid实施中删除ItemService。通常只在接口级别需要它。您的代码应如下所示。

// example implementation:
@Named
@Validated
public class ItemService implements Service<Item>{

  @Override
  public Item execute(Item item) {
    return item;
  }
}