Tomcat中的设计模式之适配器设计模式

Tomcat中的设计模式之适配器设计模式并源码举例
在Tomcat中,适配器模式通常用于将不同的请求类型(例如HTTP请求和WebSocket请求)转换为统一的接口,从而方便处理。

以HTTP请求和WebSocket请求为例,Tomcat提供了org.apache.catalina.websocket.WebSocketServlet类作为WebSocket请求处理器,但是该类并不能处理普通的HTTP请求,因此需要适配器模式将HTTP请求转换为WebSocket请求。Tomcat中提供了org.apache.catalina.websocket.WsFilter类作为WebSocket适配器,其源码如下:

public class WsFilter implements Filter {

    ...

    private WebSocketContainer getContainer() {
        if (container == null) {
            container = WebSocketContainerProvider.getWebSocketContainer();
        }
        return container;
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse resp = (HttpServletResponse) response;

        if (!getContainer().isUpgradeRequest(req, resp)) {
            chain.doFilter(request, response);
            return;
        }

        ...

        // create WebSocket endpoint and hand over to container
        ServerEndpointConfig serverEndpointConfig =
                ServerEndpointConfig.Builder.create(endpointClass, path).build();
        Endpoint endpoint = getContainer().createEndpoint(serverEndpointConfig);

        ...

        // wrap request and response with WebSocket versions and pass to endpoint
        WsServletRequestWrapper wsRequest = new WsServletRequestWrapper(req);
        WsServletResponseWrapper wsResponse = new WsServletResponseWrapper(resp);
        WsSession wsSession = new WsSession(wsRequest, wsResponse, endpoint);
        endpoint.onOpen(wsSession, serverEndpointConfig);

        ...

    }
}

在上述代码中,WsFilter类实现了Filter接口,用于拦截HTTP请求并转换为WebSocket请求。在doFilter()方法中,首先判断当前请求是否为WebSocket请求,如果不是,则将请求传递给下一个过滤器或Servlet进行处理;如果是WebSocket请求,则创建WebSocket的ServerEndpointConfig对象和Endpoint对象,并将WebSocket请求的HttpServletRequest和HttpServletResponse对象包装为WsServletRequestWrapper和WsServletResponseWrapper对象,最后调用Endpoint的onOpen()方法,处理WebSocket请求。

通过适配器模式,Tomcat实现了将HTTP请求转换为WebSocket请求的功能,同时避免了在处理WebSocket请求时需要处理HTTP请求的情况。