- 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"
.
Можете ли вы предоставить конфигурацию, используемую для обработки аннотаций @ @ Validated? –
Pls более конкретна, какую конфигурацию вы имеете в виду? Помните, что метод Rest вызывается, если я отправляю действительные или недействительные данные, '@ Validated' работает так, как ожидается. Проблема заключается в совете '@ Around'. Основная часть конфигурации описана здесь: http://stackoverflow.com/a/39842293/3665178 –
См. Раздел «Обновление 01». –