Skip to content

Instantly share code, notes, and snippets.

@mdread
Last active December 15, 2015 13:09
Show Gist options
  • Save mdread/5264964 to your computer and use it in GitHub Desktop.
Save mdread/5264964 to your computer and use it in GitHub Desktop.
Spring interceptor for conditional access to a request action
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);
}
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;
}
}
}
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);
}
}
}
<!-- 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