【问题标题】:Debugging with jstl - how exactly?使用 jstl 进行调试 - 究竟如何?
【发布时间】:2013-03-18 00:26:13
【问题描述】:

我一直在尝试了解BalusC's answer 的可调试性,但我仍然无法确切地弄清楚jstl 标记如何比scriptlet 更容易调试。

当我想到调试时,我想到的是单步调试代码并确定在任何给定点将哪些变量加载到内存中并查看其内容的能力。使用 jstl,我无法设置任何类型的断点,如果它的任何部分中断,我正在处理的任何形式的碎片都会丢失。我不确定哪个更糟:空白页面或半加载页面。我见过这样的情况:当 jstl 失败时,表单的其他部分会丢失,而不仅仅是它影响的部分。无论哪种情况,都无法真正看出问题所在。

使用 scriptlet,我可以放置断点,并在 IDE 中查看我想要的任何点。即使我没有使用这样的功能,我也可以将我想查看的任何部分程序打印到控制台,并在以后弄清楚。如果页面失败并显示一个空白页面,尽管这可能很烦人,我至少可以一步一步找出它失败的确切位置。

使用 jstl,我完全一无所知。遍历一个集合真的感觉就像一个黑盒子,你希望一切都正常,而不是真正能够一步一步地观察它的发生。它让你感到无能为力。

我承认,jstl 更简洁,看起来更直观,但我遇到的一个明显问题是无法真正调试页面上的任何内容。我在这里完全错了吗?我只是错过了调试正在发生的事情的好方法吗?还是我的调试方法不正确,需要重新考虑?

我已经用谷歌搜索了这个问题,但我似乎无法找到任何直接的答案......如果有人对此有任何见解,那将非常有帮助。我想使用 jstl 代替 scriptlet,这是让我退缩的一个明显的事情......

【问题讨论】:

  • 来自 BalusC 在您的链接中的回答:可调试性:如果 scriptlet 中途抛出异常,您得到的只是一个空白页。这是他唯一提到的部分,从不谈论 JSTL 调试。
  • 转储所有域对象可能很有用,但是在开始时查看它们中的内容并在遍历它们并对它们执行操作时查看它们中的内容是不同的故事:)。那么除了转储之外,真的没有更好的办法了吗?
  • 我已经按照您所说的做了,这可能是困难的还是容易的,这取决于您如何看待问题。一种常见的技术是Divide and conquer 很多定义,但它们指向相同的想法:将大问题分解成小块,解决每一块,然后解决大问题。所以,一步一步地添加你需要的 JSTL/EL,做一些测试等等。请注意,您可以使用<c:out> 在页面上打印某些内容(例如调试消息)。难吗?也许吧,但如果您将这些概念理解为请求属性等等,那就不是了。

标签: debugging jsp jstl


【解决方案1】:

您可以添加 jsp scriptlet 并打印 jstl 使用的变量。这会打印在控制台或容器的输出文件中

    <c:set var="myVar" value='${param.myUrlParam}' />

    <% System.out.println(pageContext.findAttribute("myVar") ); %>

这是我能找到的调试 jstl 页面的唯一最佳方法。

【讨论】:

    【解决方案2】:

    JSTL 标签本身不需要调试,如果你使用它们符合JSP/EL specificationJSTL documentation。在您找到的答案中,“可调试性”仅指用于业务逻辑的 Java 代码的上下文,需要用 Java 类(如 servlet、过滤器、实体或 EJB)替换,而不是用于表示逻辑的 Java 代码,需要被 JSTL 标签替换,例如 if/else 块、for 循环、HTML 转义、日期/数字格式、字符串操作函数等。

    但是,如果您遇到的问题已经找到了明显是 JSTL 标记的根本原因,那么如果您正确使用它们,请重新阅读 JSTL documentation。您也可以使用以下模板转储感兴趣的 EL 变量:

    <h2>Request headers</h2>
    <dl>
        <c:forEach items="${headerValues}" var="entry">
            <dt><c:out value="${entry.key}" /></dt>
            <dd>
                <c:forEach items="${entry.value}" var="headerValue" varStatus="loop">
                    <c:out value="${headerValue}" />${not loop.last ? ', ' : ''}
                </c:forEach>
            </dd>
        </c:forEach>
    </dl>
    
    <h2>Request params</h2>
    <dl>
        <c:forEach items="${paramValues}" var="entry">
            <dt><c:out value="${entry.key}" /></dt>
            <dd>
                <c:forEach items="${entry.value}" var="paramValue" varStatus="loop">
                    <c:out value="${paramValue}" />${not loop.last ? ', ' : ''}
                </c:forEach>
            </dd>
        </c:forEach>
    </dl>
    
    <h2>Request scope</h2>
    <dl>
        <c:forEach items="${requestScope}" var="entry">
            <dt><c:out value="${entry.key}" /></dt>
            <dd><c:out value="${entry.value}" /></dd>
        </c:forEach>
    </dl>
    
    <h2>Session scope</h2>
    <dl>
        <c:forEach items="${sessionScope}" var="entry">
            <dt><c:out value="${entry.key}" /></dt>
            <dd><c:out value="${entry.value}" /></dd>
        </c:forEach>
    </dl>
    
    <h2>Application scope</h2>
    <dl>
        <c:forEach items="${applicationScope}" var="entry">
            <dt><c:out value="${entry.key}" /></dt>
            <dd><c:out value="${entry.value}" /></dd>
        </c:forEach>
    </dl>
    

    如有必要,您可以将其包装在某个弹出面板中,该面板通过访问密钥打开并且仅在开发模式期间呈现(Java EE 的 MVC 框架 JSF 与 &lt;ui:debug&gt; 的风格非常相似)。

    如果徒劳无功,请将问题确定为尽可能小的 JSP 文件,该文件通过复制'n'paste'n'running 来重现整个问题(在这样的示例中,您可以放置​​必要的业务逻辑,例如 request.setAttribute() 行在放置在 JSP 文件最顶部的 scriptlet 中;这样的原型设计是 scriptlet 的合法用例之一。

    如果您仍然无法根据该 SSCCE 解决问题,请将其作为问题发布到 Stack Overflow。如果正确放置,您可能会在不到一天的时间内得到答案。如果它经常归结为简单的拼写错误或语法/逻辑错误,请不要感到惊讶。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-01
      • 2011-09-17
      • 2023-03-11
      • 2016-06-13
      • 2015-08-11
      • 1970-01-01
      • 1970-01-01
      • 2014-01-16
      相关资源
      最近更新 更多