Y a-t-il une annotation similaire à @PreAuthorize ou @PreFilter que je peux utiliser pour exécuter du code avant qu'une méthode dans le contrôleur ne soit appelée?
Je dois ajouter des informations au contexte de la requête (spécifique à la méthode appelée) pour être ensuite récupérées par le ExceptionHandler.
Par exemple
@RestController
public MyController{
@UnkwonwAnnotation("prepareContext(request.getAgentId())"){
public ResponseEntity method1(RequestA requestA) {
...
}
@UnkwonwAnnotation("prepareContext(request.getUserName())"){
public ResponseEntity method1(RequestB requestB) {
...
}
}
Je pourrais simplement utiliser @PreAuthorize mais je ne me sens pas bien
4 Réponses :
Vous pouvez ajouter un intercepteur pour cet
Exemple d'intercepteur
@Configuration
public class MyConfig extends WebMvcConfigurerAdapter{
@Override
public void addInterceptors(InterceptorRegistry registry){
registry.addInterceptor(new MyCustomInterceptor()).addPathPatterns("/**");
}
}
Configuration
Public class CustomInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request,HttpServletResponse response){
//Add Login here
return true;
}
}
J'espère que cela vous aidera
Spring Aspect est également une bonne option pour exécuter du code avant le contrôleur.
@Component
@Aspect
public class TestAspect {
@Before("execution(* com.test.myMethod(..)))")
public void doSomethingBefore(JoinPoint jp) throws Exception {
//code
}
}
Ici, myMethod () s'exécutera avant le contrôleur.
p >
Peut-être qu'une bonne option est d'implémenter un filtre personnalisé qui s'exécute à chaque fois qu'une requête est reçue.
Vous devez étendre "OncePerRequestFilter" et écraser la méthode "doFilterInternal"
public class CustomFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
//Add attributes to request
request.getSession().setAttribute("attrName", new String("myValue"));
// Run the method requested by petition
filterChain.doFilter(request, response);
//Do something after method runs if you need.
}
}
Après avoir enregistré le filtre dans Spring avec FilterRegistrationBean. Si vous avez la sécurité Spring, vous devez ajouter votre filtre après le filtre de sécurité.
Le filtre ne saurait pas quels paramètres la méthode a reçus
Oui, vous avez l'objet de requête dans la méthode oFilterInternal , ici il y a tous les paramètres ... vous pouvez travailler avec tous. Tapez simplement request.getParameterNames () // pour donner tous les noms. request.getParameter ("myParam") // pour obtenir la valeur d'un paramètre
De cette façon, le filtre serait encombré d'instructions IF. Je voudrais une annotation pour aller sur la méthode qui l'exige
Dans ce cas, la meilleure option est d'utiliser un intercepteur. Ma solution est globale, affecte toutes les demandes.
Cela signifie toujours que la logique de chaque contrôleur sera au même endroit
Oui, la logique que vous mettez dans le filtre fonctionnera pour les requêtes adressées à tous les contrôleurs.
En développant la réponse de Sai Prateek, j'ai créé une annotation personnalisée:
@RestController
public class MyController {
@OperationContext(clientId = '#request.getClientId', userId = '#request.getUserId', operation = "OPERATION_A")
public ResponseEntity aMethod(MyRequest request) {
...
}
}
et un composant pour la gérer:
@Aspect
@Component
public class OperationContextAspect {
@Before(value = "@annotation(operationContext)", argNames = "operationContext")
public void preHandle(OperationContext operationContext) {
RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
requestAttributes.setAttribute("operation", operationContext.operation, RequestAttributes.SCOPE_REQUEST);
requestAttributes.setAttribute("clientId", operationContext.clientId(), RequestAttributes.SCOPE_REQUEST);
requestAttributes.setAttribute("userId", operationContext.userId(), RequestAttributes.SCOPE_REQUEST);
}
}
J'annote ensuite les méthodes du contrôleur en fournissant les paramètres requis:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationContext {
String clientId();
String userId();
String operation();
}
C'est à cela que sert un
HandlerInterceptor. Implémentez la méthodepreHandleet faites votre travail.