通过添加全局过滤器实现根据内容分发到不同应用

项目背景:

    tomcat 6 + JDK6 + Linux
    现有应用(无维护厂商, 有知识产权不得改代码, 总之就是不能动) : WebApp0, 
        提供一个WebService作为入口: /WebApp0/Service

    新系统(实现了新的业务逻辑,作为老系统的补充, 能够完全控制代码): WebApp1,
        同样提供WebService作为入口:/WebApp1/Service

分析:

    由于所有的业务都指向了WebApp0/Service, 然而现有系统不能二次开发, 只能在用户请求到达WebApp0之前做分发. Tomcat的过滤器(filter)可以帮助我们实现这一目标.
    Tomcat过滤器是针对根(/)进行过滤,也就是全局过滤. 配置文件放在{tomcatRoot}/conf/web.xml
    同时,由于需要跨域(/WebApp0和/WebApp1),需要修改Tomcat的安全配置.{tomcatRoot}/conf/context.xml

代码实现:

Filter:
xx

package org.mylab.container.filter;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;

/**
 * Created by CasparLi on 03/03/2015.
 * 所有的用户请求都指向http://localhost/WebApp0/Service, 
 * 而新逻辑部署在http://localhost/WebApp1/Service.
 * 根据请求内容中是否包含关键字"OOXX"判断走新逻辑还是老逻辑.
 */
public class TestFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("TestFilter init!");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        String requestURL = httpRequest.getRequestURL().toString();
        System.out.println("TestFilter requestURL : " + requestURL);
        String msg;
        BufferedReader reader = request.getReader();
        msg = reader.readLine();
        if (msg == null || msg.isEmpty()) {
            System.out.println("TestFilter read msg failed.");
            chain.doFilter(request, response);
            return;
        } else {
            System.out.println("TestFilter read msg success: " + msg);
        }
        reader.reset(); // 这里必须要reset, 否则转发后取不到数据.
        if (msg.contains("OOXX")) {
            System.out.println("TestFilter got OOXX forward to WebApp1");
            ServletContext rootContext = httpRequest.getServletContext(); //取根的上下文. 根路径是: http://localhost/
            ServletContext app01Context = rootContext.getContext("/WebApp1");
            System.out.println("Got context:" + app01Context);
            RequestDispatcher dispatcher = app01Context.getRequestDispatcher("/Service"); //这里取的是WebApp1的上下文, 根路径就成了: http://localhost/WebApp1/ 所以只需要写/Service
            System.out.println("Got dispatcher :" + dispatcher);
            dispatcher.forward(request, response);
        } else {
            chain.doFilter(request,response);
        }

    }

    @Override
    public void destroy() {
        System.out.println("TestFilter has be destroyed");
    }

}

Filter写好后需要打成jar包, 放到{tomcatRoot}/lib中才能被Tomcat使用. 付一个maven的打包脚本:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.mylab</groupId>
    <artifactId>ContainerFilter</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <jdk.version>1.6</jdk.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.3.2</version>
                <configuration>
                    <source>${jdk.version}</source>
                    <target>${jdk.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
        </dependency>
    </dependencies>

</project>


Tomcat的web.xml配置


<!-- MyFilter -->
<filter>
  <filter-name>MyDispatcher</filter-name>
  <filter-class>org.mylab.container.filter.TestFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>MyDispatcher</filter-name>
  <!-- 这里是全局过滤器, 必须mapping到根上, 否则过滤器不起效 -->
  <url-pattern>/*</url-pattern>
</filter-mapping>
这时运行Tomcat, 过滤器应该已经生效, 并能够根据内容对用户请求分发. 但会报空指针错误. 这是因为请求跨域了(从/跨到/WebApp1). 要解决这个问题就要配置Tomcat的参数, 使得支持跨域.
修改{tomcatRoot}/conf/context.xml 在 Context节点上添加 crossContext="true"属性, 其默认值是false, 跨域取ServletContext会返回null. 
<Context crossContext="true">



现在重启Tomcat, 请求就能正确分发了.

转载于:https://my.oschina.net/CasparLi/blog/382579

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值