Last active
December 15, 2015 13:09
-
-
Save mdread/5264964 to your computer and use it in GitHub Desktop.
Spring interceptor for conditional access to a request action
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.caoticode.spring.interceptors.conditional; | |
import javax.servlet.http.HttpServletRequest; | |
import org.springframework.context.ApplicationContext; | |
public interface AccessCondition { | |
boolean test(HttpServletRequest request, ApplicationContext context); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.caoticode.spring.interceptors.conditional; | |
import java.lang.annotation.ElementType; | |
import java.lang.annotation.Retention; | |
import java.lang.annotation.RetentionPolicy; | |
import java.lang.annotation.Target; | |
import javax.servlet.http.HttpServletRequest; | |
import org.springframework.context.ApplicationContext; | |
@Target({ ElementType.TYPE, ElementType.METHOD }) | |
@Retention(RetentionPolicy.RUNTIME) | |
public @interface ConditionalAccess { | |
Class<? extends AccessCondition> testClass() default DefaultAccessCondition.class; | |
String testScript() default ""; | |
String action() default ""; | |
public static class DefaultAccessCondition implements AccessCondition { | |
@Override | |
public boolean test(HttpServletRequest request, ApplicationContext context) { | |
return true; | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package net.caoticode.spring.interceptors.conditional; | |
import java.io.IOException; | |
import javax.script.Bindings; | |
import javax.script.ScriptEngine; | |
import javax.script.ScriptEngineManager; | |
import javax.script.ScriptException; | |
import javax.script.SimpleBindings; | |
import javax.servlet.ServletException; | |
import javax.servlet.http.HttpServletRequest; | |
import javax.servlet.http.HttpServletResponse; | |
import org.springframework.beans.BeansException; | |
import org.springframework.context.ApplicationContext; | |
import org.springframework.context.ApplicationContextAware; | |
import org.springframework.web.method.HandlerMethod; | |
import org.springframework.web.servlet.HandlerInterceptor; | |
import org.springframework.web.servlet.ModelAndView; | |
import com.regesta.opac.asc.interceptors.conditional.ConditionalAccess.DefaultAccessCondition; | |
public class ConditionalAccessInterceptor implements HandlerInterceptor, ApplicationContextAware { | |
ApplicationContext applicationContext; | |
ScriptEngineManager manager = new ScriptEngineManager(); | |
ScriptEngine engine = manager.getEngineByName("JavaScript"); | |
@Override | |
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { | |
this.applicationContext = applicationContext; | |
} | |
@Override | |
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex3) throws Exception { | |
} | |
@Override | |
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView model) throws Exception { | |
} | |
@Override | |
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { | |
if (handler instanceof HandlerMethod) { | |
HandlerMethod handlerMethod = (HandlerMethod) handler; | |
ConditionalAccess ca = getAnnotation(handlerMethod); | |
if (ca != null) { | |
boolean result = true; | |
if (!ca.testScript().isEmpty()) { | |
result = evalScript(ca.testScript(), request); | |
} | |
if (!ca.testClass().equals(DefaultAccessCondition.class)) { | |
AccessCondition cond = ca.testClass().newInstance(); | |
result = result && cond.test(request, applicationContext); | |
} | |
if (!result) { | |
invokeAction(ca.action(), request, response); | |
return false; | |
} | |
} | |
} | |
return true; | |
} | |
private ConditionalAccess getAnnotation(HandlerMethod handler) { | |
ConditionalAccess annotation = handler.getMethodAnnotation(ConditionalAccess.class); | |
if (annotation == null) { | |
Class<?> beanType = handler.getBeanType(); | |
annotation = beanType.getAnnotation(ConditionalAccess.class); | |
} | |
return annotation; | |
} | |
private boolean evalScript(String script, HttpServletRequest request) throws ScriptException { | |
Bindings bindings = new SimpleBindings(); | |
bindings.put("request", request); | |
bindings.put("session", request.getSession()); | |
bindings.put("context", applicationContext); | |
return ((Boolean) engine.eval(script, bindings)).booleanValue(); | |
} | |
private void invokeAction(String action, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { | |
String actionType = action.substring(0, action.indexOf(':')); | |
String url = action.substring(actionType.length() + 1); | |
if (actionType.equals("redirect")) { | |
response.sendRedirect(request.getContextPath() + url); | |
} else if (actionType.equals("forward")) { | |
request.getRequestDispatcher(request.getContextPath() + url).forward(request, response); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- add ConditionalAccessInterceptor to the Spring configuration --> | |
<interceptors> | |
<beans:bean class="net.caoticode.spring.interceptors.conditional.ConditionalAccessInterceptor" /> | |
</interceptors> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment