You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Java/Spring/Tomcat环境下的webapp1.war嵌入webapp2.war内容?

解决方案:在webapp1中访问webapp2的内容

这是个很实际的场景,我来给你拆解下可行的方案和需要注意的坑:

先讲为啥直接用JSP include不行

咱们平时用的<jsp:include>或者<%@ include %>都是针对同一个Web应用内部的资源加载,Tomcat默认会隔离不同Web应用的类加载器和上下文,跨应用直接用include标签会直接报错,因为根本找不到webapp2的资源路径。

可行的三种方案

1. 写一个内部代理组件(无需修改Tomcat配置)

在webapp1里新增一个Servlet或者Spring Controller,作为“中间层”,帮用户转发请求到webapp2,再把响应返回给用户。具体步骤:

  • 因为两个应用在同一台服务器上,你可以用本地地址调用webapp2,比如http://localhost:8080/webapp2/xxx(安全团队禁止的是外部访问,内部本地请求通常是允许的,先确认这点)
  • 代码示例(用Spring Controller举例):
    @GetMapping("/webapp2-proxy/**")
    public ResponseEntity<Object> proxyToWebapp2(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 获取用户请求的webapp2路径(去掉前缀/webapp2-proxy)
        String path = request.getRequestURI().replace("/webapp2-proxy", "");
        String webapp2Url = "http://localhost:8080/webapp2" + path;
    
        // 复制用户的请求头(尤其是SSO相关的Cookie,确保webapp2能识别用户身份)
        HttpHeaders headers = new HttpHeaders();
        Enumeration<String> headerNames = request.getHeaderNames();
        while (headerNames.hasMoreElements()) {
            String headerName = headerNames.nextElement();
            headers.add(headerName, request.getHeader(headerName));
        }
    
        // 发送请求到webapp2
        HttpEntity<String> entity = new HttpEntity<>(headers);
        ResponseEntity<String> webapp2Response = restTemplate.exchange(webapp2Url, HttpMethod.valueOf(request.getMethod()), entity, String.class);
    
        // 把webapp2的响应返回给用户
        return ResponseEntity.status(webapp2Response.getStatusCode())
                .headers(webapp2Response.getHeaders())
                .body(webapp2Response.getBody());
    }
    
  • 注意点:要处理Cookie、请求方法(GET/POST)、文件上传这些特殊场景,还要防范SSRF风险——必须严格限制请求只能指向本地的webapp2,不能让用户篡改目标URL。

2. 配置Tomcat跨上下文访问(需要服务器权限)

Tomcat支持开启跨上下文访问,让webapp1直接获取webapp2的上下文,从而转发请求:

  • 修改Tomcat的conf/server.xml,给两个应用的<Context>节点加上crossContext="true":
    <Context path="/webapp1" docBase="webapp1.war" crossContext="true"/>
    <Context path="/webapp2" docBase="webapp2.war" crossContext="true"/>
    
  • 然后在webapp1的JSP或Servlet里,就可以直接转发请求到webapp2:
    // 在Servlet里的写法
    ServletContext webapp2Context = getServletContext().getContext("/webapp2");
    RequestDispatcher dispatcher = webapp2Context.getRequestDispatcher("/index.jsp");
    // 转发请求,用户看不到webapp2的地址
    dispatcher.forward(request, response);
    
  • 注意点:这个方案需要修改Tomcat全局配置,得和运维/服务器管理员沟通;另外安全团队可能会顾虑跨上下文打破了应用隔离,要提前确认安全性。

3. 合并两个应用(最简单但耦合性高)

如果webapp2的功能不复杂,直接把webapp2的代码、JSP、静态资源全部复制到webapp1里,重新打包成一个war包。这样就不存在跨应用访问的问题了,但缺点是两个应用会耦合在一起,后续单独维护会很麻烦,适合小体量的应用。

安全必注意的点

  • 不管用哪种方案,都要确保webapp2的内容只能被已通过SSO认证的用户访问——代理/转发的请求必须带上用户的SSO凭证(比如Cookie),不能让匿名用户通过webapp1访问webapp2。
  • 如果用代理方案,一定要严格校验目标URL,防止被用来发起恶意内部请求(SSRF攻击)。

内容的提问来源于stack exchange,提问作者user550738

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:49:33