使用spring构建一个façade,调用另一个服务器并返回其响应

时间:2015-06-11 13:24:05

标签: spring rest interceptor facade

对于应用程序,我需要在Spring 4.x中创建一个安全外观。

这个薄层必须接受来自我们移动应用程序的任何请求,并对提供的令牌执行安全检查(使用openId和Oauth)。

验证成功后,需要将请求转发到后端应用程序,后端应用程序无需了解安全令牌机制。

因此,流程将是这样的: security_facade_url /路径/的/中/请求

使用标题指示成功验证令牌后要调用的后端

成功验证后,安全性外观会向后端URL发送请求 backend_application_url /路径/的/中/请求

façade必须没有映射到请求的任何可能路径的控制器,但必须根据请求标头中的值在正确的后端服务器上调用请求。然后将此响应返回给用户。

到目前为止,我是HandlerInterceptor的一个实现。但是,这个拦截器有效,我对我需要通过在postHandle方法中抛出异常来避免afterCompletion的方式感到满意。 如果我没有抛出错误,则在afterCompletion步骤中将默认错误页面附加到正确的响应中。

到目前为止,这是我的代码:

public class RequestProcessingInterceptor implements HandlerInterceptor {    
private final Logger log = LoggerFactory.getLogger(RequestProcessingInterceptor.class);

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
    log.info("Doing some security stuff now ...");

    log.warn("... security ok ... since I am not really checking stuff");
    return true;
}

public void postHandle(HttpServletRequest request,
                       HttpServletResponse response, Object handler,
                       ModelAndView modelAndView) throws Exception {
    log.info("Forwarding request and sending that info back ...");

    ClientConfig config = new DefaultClientConfig();
    Client client = Client.create(config);
    WebResource service = client.resource(UriBuilder.fromUri("http://localhost:8080").build());

    response.setContentType("application/json");
    response.getWriter().write(service.path(modelAndView.getModel().get("path").toString()).accept("application/json").get(String.class));
    response.setStatus(200);

    throw new Exception("Need to avoid the execution of the afterCompletion. Only way to do so is by throwing an exception...");
}

public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {

}

}

是否有更合适的方式来干预Spring生命周期或获得上述行为?

2 个答案:

答案 0 :(得分:1)

找到了更好的解决方案。根据我的需要,我不需要在拦截器中操纵结果。

更简洁的方法是定义一个使用请求方法映射的Controller。

@RequestMapping(method = {RequestMethod.GET, RequestMethod.PUT, RequestMethod.POST})
public void handleRequest(HttpServletRequest request, HttpServletResponse response) { // code omitted }

答案 1 :(得分:0)

您不应该试图避免拨打afterCompletion。只需实现一个空方法,让SpringFramework调用它。

如果您的控制器返回null,表示不必调用任何视图,它应该可以使用更顺畅的Spring集成。

但是我不明白为什么你在这里使用Spring MVC。由于您只与低级HttpServletRequest和HttpServletResponse进行交互,因此您也可以使用:

  • 负责将请求和响应中继到后端并在响应中写入返回值的专用servlet
  • 在将请求传递给过滤器链之前执行安全性操作的过滤器