2016-10-06 15 views
0

Я работаю сTest & АОП Spring MVC: Around совет не выполняется, как ожидается, для контроллера покоя (только для недостоверных данных)

  • Spring Framework 4.3.3
  • AspectJ 1.8.9

У меня есть два @Controllers один для mvc и другие для rest. Каждый использует, как зависимость a @Service.

У меня есть следующий Rest методы

package com.manuel.jordan.controller.persona; 

@Controller 
@RequestMapping(value="/personas") 
public class PersonaRestController { 

    @PutMapping(value="/{id}", consumes={MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_UTF8_VALUE}) 
    public ResponseEntity<Void> updateOne(@PathVariable String id, @Validated @RequestBody Persona persona){ 
     persona = personaService.updateOne(persona); 
     return ResponseEntity.noContent().build(); 
    } 

Наблюдайте для второго параметра я использую @Validated

У меня есть следующие Pointcut:

@Pointcut(value= 
"execution(* com.manuel.jordan.controller.persona.PersonaRestController.updateOne(..))") 
public void updateOnePointcut(){} 

И следующее Around Советов:

@Around(value="PersonaRestControllerPointcut.updateOnePointcut()") 
@Transactional(noRollbackFor={Some exceptions}) 
public Object aroundAdviceUpdateOne(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { 

    logger.info("Beginning aroundAdviceUpdateOne - Class: {}, Method: {}", 
    proceedingJoinPoint.getTarget().getClass().getSimpleName(), 
    proceedingJoinPoint.getSignature().getName()); 

    .... 

} 

Через Spring MVC Test

Когда я посылаю достоверные данные:

Такие как:

resultActions = mockMvc.perform(put(uri).contentType(MediaType.APPLICATION_JSON_UTF8) 
         .accept(MediaType.APPLICATION_JSON_UTF8) 
         .header("Accept-Language", locale.toString()) 
.content(JsonTransformerSupport.objectToJson(personaValid))).andDo(print()); 

или по

RequestEntity<Persona> requestEntity = RequestEntity.put(uri).contentType(MediaType.APPLICATION_JSON_UTF8)                    
.accept(MediaType.APPLICATION_JSON_UTF8) 
.header("Accept-Language", locale.toString())                   
.body(personaValid); 

Через Gradle отчеты я могу подтвердить, что @Around совет работает, как это ожидается. Он просто просматривает текст Beginning aroundAdviceUpdateOne - Class .... в отчете, а остальные члены совета работают, как ожидается.

проблема когда я отправить недопустимые данные для тестирования через @Validated

Использования показаны выше двух способов, но только изменяя personaValid от personaInvalid (нулевых полей, нарушая минимальные и максимальные границы, и т.д.) я сделал осознать, что совет @Around всегда игнорируется. Это подтверждает, что Beginning aroundAdviceUpdateOne - Class ....никогда не появляется.

Примечание: даже если совет @Around не работает, процесс проверки происходит. Я имею в виду, что исключений нет. Метод @Test проходит.

Вот некоторые соображения.

  • У меня такое же поведение с @Before совет.
  • Я предполагаю передвыполнение из PersonaRestController.updateOne метода @Around (даже @Before) совет должен делать свою работу. Без материальных данных данные действительны или нет.
  • У меня есть этот сценарий вполне справедливо, когда я отправить данные либо действительные или недействительные к не- отдыха контроллер

Этот метод:

@PutMapping(value="/update/{id}", 
      consumes=MediaType.APPLICATION_FORM_URLENCODED_VALUE, 
      produces=MediaType.TEXT_HTML_VALUE) 
public String updateOne(@PathVariable String id, 
      @Validated @ModelAttribute Persona persona, 
      BindingResult result, 
      RedirectAttributes redirectAttributes){ 

же@Around совет работает, только со следующим изменением (примечание к ||):

@Around(value="PersonaRestControllerPointcut.updateOnePointcut() || PersonaControllerPointcut.updateOnePointcut()") 
@Transactional(noRollbackFor={some exceptions }) 
public Object aroundAdviceUpdateOne(JoinPoint proceedingJoinPoint) throws Throwable { 

Update 01

Поэтому 4 сценариев, где @Around совет должен работать:

  • , не метод отдыха с действительными данными (работ)
  • , не метод отдыха с некорректными данными (работ)
  • метод отдыха с действительными данными (работ)
  • метод останова с недопустимыми данными (сбой или игнорирование - @Around не выполняется)

Снова: @Validated работает, как ожидается для отдыха и не отдыхающих. Проблема о совете @Around, он не работает , когда метод Rest выполняется только при отправке неверных данных. Что не так? или отсутствует?

Обновление 02

@Validated является:

Вариант Действительно, поддерживающих спецификацию проверки групп JSR-303 в. Предназначен для удобного использования с поддержкой Spring, JSR-303, но не JSR-303 конкретной

его из API

КАЖЕТСЯ не является AOP аннотаций. Это просто аннотация «Весна». Мои @Pointcut не заботятся или не проверяют аннотации. Он использует updateOne(..)

Обновление 03

даже при прибавлении

@Aspect 
@Component 
@Transactional 
@Order(0) 
class PersonaRestControllerAspect { 

Не работает, как ожидается.

Update 04

У меня есть

@EnableWebMvc 
@Configuration 
public class WebMvcConfig extends WebMvcConfigurerAdapter { 

... 

    @Override 
    public Validator getValidator() { 
     return validatorConfig.localValidatorFactoryBean(); 
    } 

... 

Где Validator приходит от:

@Bean 
public LocalValidatorFactoryBean localValidatorFactoryBean(){ 
    LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean(); 
    localValidatorFactoryBean.setValidationMessageSource(rrbms); 
    return localValidatorFactoryBean; 
} 

Это rrbms является ReloadableResourceBundleMessageSource экземпляр, загружать множество .properties файлов, один из них "classpath:/com/manuel/jordan/validation/validation".

+0

Можете ли вы предоставить конфигурацию, используемую для обработки аннотаций @ @ Validated? –

+0

Pls более конкретна, какую конфигурацию вы имеете в виду? Помните, что метод Rest вызывается, если я отправляю действительные или недействительные данные, '@ Validated' работает так, как ожидается. Проблема заключается в совете '@ Around'. Основная часть конфигурации описана здесь: http://stackoverflow.com/a/39842293/3665178 –

+0

См. Раздел «Обновление 01». –

ответ

1

Это ожидаемое поведение. Если вы используете @Validated без сопровождающего параметра BindingResult, метод никогда не вызывается. Вы получаете исключение, если данные недействительны. В конце концов, это весь смысл проверки. И если метод не вызывается, ваш совет также не будет выполнен.

+0

Метод Rest вызывается, если я отправляю действительные или недействительные данные, '@ Validated' работает так, как ожидается. Проблема заключается в совете '@ Around'. –

+0

См. Раздел «Обновление 01». –

+0

@ManuelJordan Без параметра BindingResult метод не вызывается (должен быть), когда данные недействительны. Это не имело никакого смысла. Если это действительно называется в вашем случае, то это проблема. – zeroflagL

 Смежные вопросы

  • Нет связанных вопросов^_^