2015-03-30 3 views
5

Momentan migrieren wir ein Struts 1.1-Projekt in Spring 4.x.Java - Wie kombiniere ich Validierungs- und AOP-Annotationen und verwende sie im Spring Controller?

Wir haben Action-Klasse erfolgreich in Controller und Formbean in Model konvertiert und sogar können wir die Struts-Validierung in Spring-Validierung konvertieren.

Aber wir stehen vor einem Problem, wenn wir versuchen, AOP für alle Controller hinzuzufügen. Der Zweck besteht darin, ein Protokoll hinzuzufügen, um die für alle Controller-Methoden benötigte Zeit zu messen.

unten ist Code-Schnipsel,

@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"); 
    } 
} 

wir die untenstehende Punkt-Schnitt AOP wird

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; 
    } 
} 

Entweder Validation oder AOP zu einem Zeitpunkt arbeiten anzuwenden verwenden. Wenn AOP nicht angewendet wird, wird die Validierung ausgelöst. Wenn AOP angewendet wird, wird nur AOP ausgelöst.

Kann mir jemand helfen?

Danke ...

+0

Ich bin in der Lage, das Problem zu replizieren. Etwas, das mit der Art und Weise, wie Sie Aspekte verwenden, wörtlich wird. Nach einer Lösung suchen. Bitte schauen Sie, ob dieser Link Ihnen hilft. http: //forum.springio/forum/spring-projekte/web/64867-controller-kombinieren-mit-aspekt-kann-t-arbeiten .. – ArunM

Antwort

0

Ich habe das funktioniert. Sie müssen 2 Änderungen vornehmen. Kein

Wechsel: 1

  1. Ihre Aspect Definition ist falsch aus irgendeinem Grund (keine Ahnung warum).. Aber der folgende Aspekt wird funktionieren.

    @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()); 
    } 
    

    }

ändern No: 2

initBinder sollte als öffentlich deklariert werden. Momentan haben Sie diese Methode als privat definiert. Wieder bin ich mir nicht sicher, warum das ohne die Aspekte richtig funktioniert.

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

Die 2 Änderungen funktionieren.

+0

Danke für Ihren wertvollen Kommentar. Lass mich das überprüfen –

0

Eigentlich sollte Aruns Version keinen großen Unterschied machen außer sauberer (wie allgemeiner) und ausführlicher zu sein, es sei denn, Selvakumars Pointcut ist falsch. Da er uns keine Paketnamen für Aspekte oder Controller zeigt, ist dies spekulativ, aber vielleicht befindet sich der Controller nicht direkt in Paket com.controller, sondern in einigen Unterpaketen. In diesem Fall sollte die pointcut eher

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

sein Bitte nicht die Doppelpunktsyntax .. was in etwa bedeutet „eine beliebige Anzahl von Unterpaket Ebenen“.

Verwandte Themen