2015-03-30 13 views
5

Attualmente stiamo migrando un progetto Struts 1.1 in Spring 4.x.Java - Come combinare le annotazioni Validation e AOP e usarlo in Spring Controller?

Abbiamo convertito con successo la classe Action in Controller e formbean in Model e persino siamo in grado di convertire la convalida dei montanti in validazione Spring.

Ma siamo di fronte a un problema quando proviamo ad aggiungere AOP per tutti i controller. Lo scopo è aggiungere un registro per misurare il tempo impiegato per tutti i metodi del controller.

sotto è frammento di codice,

@Component 
@Controller 
public class LoginController { 

    @Autowired 
     private LoginValidator loginValidator; 

    @InitBinder 
    private void initBinder(WebDataBinder binder) { 
     binder.setValidator(loginValidator); 
    } 

    @RequestMapping(value = "/login", method = RequestMethod.POST) 
    public String loginUser(@Valid @ModelAttribute Login form, BindingResult bindingResult) { 
    System.out.println("Entering loginController.loginUser method"); 
    } 
} 

Utilizziamo il taglio a punto indicato qui per applicare AOP,

import org.aspectj.lang.ProceedingJoinPoint; 
import org.aspectj.lang.annotation.Around; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Pointcut; 
import org.springframework.stereotype.Component; 

@Component 
@Aspect 
public class Logging { 

    @Pointcut("execution(* com.controller.*.*(..))") 
    public void businessLogicMethods() {} 

    @Around("businessLogicMethods()") 
    public Object logAround(ProceedingJoinPoint jp) { 

    System.out.println("around() is running!"); 
    System.out.println(jp.getSignature().getName()); 
    System.out.println(jp.getArgs()); 
    Object obj = null; 
    try { 
     obj = jp.proceed(); 
    } catch (Throwable e) { 
     e.printStackTrace(); 
    } 
    System.out.println("******"); 
    return obj; 
    } 
} 

O convalida o AOP sta lavorando alla volta. Se AOP non viene applicato, viene eseguita la convalida. Se aop viene applicato, viene attivato solo AOP.

Qualcuno può aiutare in questo?

Grazie ...

+0

Sono in grado di replicare il problema. Qualcosa si strugge nel modo in cui stai usando gli aspetti. Controllo di una soluzione. Si prega di vedere se questo collegamento ti aiuterà. http: //forum.spring.io/forum/spring-projects/web/64867-controller-combine-con-aspetto-can-t-work .. – ArunM

risposta

0

Ho ottenuto questo funzionamento. Devi fare 2 cambiamenti.

Cambio No: 1

  1. tua definizione Aspect è sbagliato per qualche motivo (Nessuna idea perché).. Ma l'aspetto sottostante funzionerà.

    @Component 
    @Aspect 
    public class Logging { 
    
    static final Logger LOG = LoggerFactory.getLogger(Logging.class); 
    
    @Pointcut("within(@org.springframework.stereotype.Controller *)") 
    public void controller() {} 
    
    @Pointcut("execution(* *(..))") 
    public void methodPointcut() {} 
    
    @Pointcut("within(@org.springframework.web.bind.annotation.RequestMapping *)") 
    public void requestMapping() {} 
    
    @Before("controller() && methodPointcut() && requestMapping()") 
    public void aroundControllerMethod(JoinPoint joinPoint) throws Throwable { 
        LOG.info("Invoked: " + niceName(joinPoint)); 
    } 
    
    @AfterReturning("controller() && methodPointcut() && requestMapping()") 
    public void afterControllerMethod(JoinPoint joinPoint) { 
        LOG.info("Finished: " + niceName(joinPoint)); 
    } 
    
    private String niceName(JoinPoint joinPoint) { 
        return joinPoint.getTarget().getClass() 
          + "#" + joinPoint.getSignature().getName() 
          + "\n\targs:" + Arrays.toString(joinPoint.getArgs()); 
    } 
    

    }

Cambio No: 2

initBinder dovrebbero essere dichiarati come public. Attualmente questo metodo è stato definito come privato. Ancora una volta non sono sicuro del perché funzioni correttamente senza gli aspetti.

@InitBinder 
    public void initBinder(WebDataBinder binder) { 
     binder.setValidator(loginValidator); 
    } 

Le 2 modifiche funzioneranno.

+0

Grazie per il tuo prezioso commento. Fammi controllare –

0

In realtà la versione di Arun non dovrebbe fare una grande differenza se non quella di essere più puliti (come in generale) e più prolissi, a meno che il punto di taglio di Selvakumar sia sbagliato per cominciare. Poiché non ci sta mostrando alcun nome di pacchetto per aspetto o controller, questo è speculativo, ma forse il controller non risiede direttamente nel pacchetto com.controller ma all'interno di qualche sottoprogetto. In questo caso il pointcut dovrebbe piuttosto essere

@Pointcut("execution(* com.controller..*(..))") 

Per favore, non il punto di sintassi doppia .. che significa grosso modo "includere qualsiasi numero di livelli sub-package".

Problemi correlati