【问题标题】:How do I call a second JSP servlet while in the first JSP servlet?如何在第一个 JSP servlet 中调用第二个 JSP servlet?
【发布时间】:2011-10-21 16:25:37
【问题描述】:

假设我提交了一个简单的页面(没有参数、没有表单等,并且我无法向该页面添加任何内容),我最终进入了第一个 servlet。现在我确定是时候在第二个 servlet 中做这些事情了。第二个 servlet 需要填充一堆参数和表单字段,所以首先我需要在第一个 servlet 中设置它们,然后弄清楚如何将这些东西传递给第二个 servlet。当我尝试向参数映射中添加某些内容时,它会出错并显示“不允许对锁定的参数映射进行修改”(这是 JSP 应该工作的方式)。我在想也许我应该实例化另一个请求对象,但我不知道该怎么做(并且让自己远离热水)。如果在第一个 servlet 中,我能够用所有“正确的东西”构造一个请求对象,那么我需要使用该请求运行第二个 servlet,并让它带我到第二个 servlet 重定向的任何页面我也是。我认为这只是一个 response.sendRedirect();

如何获取第一个 servlet 中定义的附加参数和内容,以便在执行 sendRedirect 时,第二个 servlet 拥有它需要的一切?

【问题讨论】:

    标签: jsp servlets redirect


    【解决方案1】:

    调用其他 servlet 的正常方法是使用 RequestDispatcher#include()

    request.getRequestDispatcher("/secondServletURL").include(request, response);
    

    如果你想添加额外的请求参数并且你想在重定向页面的(书签!)URL中结束它们,那么你必须根据以下内容填充查询字符串在重定向之前自己设置这些参数。

    response.sendRedirect(request.getContextPath() + "/secondServletURL?" + queryString);
    

    您可以按如下方式创建查询字符串:

    Map<String, String[]> params = new HashMap<String, String[]>(request.getParameterMap());
    params.put("name1", new String[] {"value1"});
    params.put("name2", new String[] {"value2"});
    // ...
    
    String queryString = toQueryString(params);
    

    toQueryString() 如下所示:

    public static String toQueryString(Map<String, String[]> params) {
        StringBuilder queryString = new StringBuilder();
    
        for (Entry<String, String[]> param : params.entrySet()) {
            for (String value : param.getValue()) {
                if (queryString.length() > 0) {
                    queryString.append("&amp;");
                }
    
                queryString
                    .append(URLEncoder.encode(param.getKey(), "UTF-8"))
                    .append("=")
                    .append(URLEncoder.encode(value, "UTF-8"));
            }
        }
    
        return queryString.toString();
    }
    

    但是,由于该 servlet 似乎在同一个容器中运行,并且您希望重用第二个 servlet 的逻辑而不将其他参数公开,那么可能更好的方法是重构该紧的业务代码将第二个 servlet 耦合到另一个独立且可重用的类中,您最终只需在两个 servlet 中导入并调用该类。然后,您可以使用可重用的 Javabean 对象将数据传递给该类。

    例如,servlet 1:

    SomeData data = new SomeData();
    data.setSomeProperty1(request.getParameter("someProperty1"));
    data.setSomeProperty2("some custom value");
    data.setSomeProperty3("some other custom value");
    
    SomeBusinessService service = new SomeBusinessService();
    service.doSomeAction(data);
    

    还有 servlet 2:

    SomeData data = new SomeData();
    data.setSomeProperty1(request.getParameter("someProperty1"));
    data.setSomeProperty2(request.getParameter("someProperty2"));
    data.setSomeProperty3(request.getParameter("someProperty3"));
    
    SomeBusinessService service = new SomeBusinessService();
    service.doSomeAction(data);
    

    SomeBusinessService 通常是一个 EJB。

    【讨论】:

    • 谢谢!我应该说“第二个 servlet”正在扩展一些东西,这些东西正在扩展一些与供应商代码挂钩的东西,而我没有源代码来最终扩展 HttpServlet。因此,重构往往变得相当棘手。将查询参数添加到重定向 URL 并不是很漂亮,但它确实有效!谢谢。
    • 啊,我明白了。好吧,您可以根据请求参数映射创建一个新映射,将新参数放入其中并将其传递给某个实用程序方法。另请参阅答案更新。
    猜你喜欢
    • 1970-01-01
    • 2012-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-25
    • 2011-05-14
    • 2016-04-01
    相关资源
    最近更新 更多