JSTL 与 JSP Scriptlet

发布于 2024-10-09 05:41:56 字数 677 浏览 2 评论 0原文

我希望有人能解释一下 BlausC 在这个问题中令人惊奇的答案中的一些观点。

他说 scriptlet 有一些缺点,它们是:

  1. 可重用性:你不能重用 scriptlet。我的问题:如何重用 JSTL 代码?

  2. 可替换性:您不能使 scriptlet 变得抽象。抽象是什么意思以及 JST 如何变得抽象?

  3. OO:你不能使用继承/组合。我如何在 JSTL 中使用 OO 范例?

  4. 调试:如果 scriptlet 中途抛出异常,您得到的只是一个空白页。

  5. 可测试性:scriptlet 无法进行单元测试。这是什么意思?如何对 JSTL 进行单元测试?

  6. 可维护性:根据 saldo 的说法,需要更多时间来维护混合/混乱/重复的代码逻辑。这意味着什么?

最后,他引用了Oracle的建议:

JSP scriptlet 不应用于编写业务逻辑。

在 MVC 模式中,我仅在表示层中使用 scriptlet。他在这里是什么意思?

I want someone to explain some points in BlausC's amazing answer in this question.

He said that scriptlets had some disadvantages, which are:

  1. Reusability: you can't reuse scriptlets. My question : how could I reuse JSTL code?

  2. Replaceability: you can't make scriptlets abstract. What does abstract mean and how could JST become abstract?

  3. OO: you can't make use of inheritance/composition. How could I use OO paradigms in JSTL?

  4. Debugging: if a scriptlet throws an exception halfway, all you get is a blank page.

  5. Testability: scriptlets can't be unit tested. What does that mean, and how can JSTL be unit tested?

  6. Maintainability: per saldo, more time is needed to maintain mingled/cluttered/duplicated code logic. What does this mean?

The last thing is what he quoted form Oracle's recommendation:

JSP scriptlets should not be used for writing business logic.

In the MVC pattern, I use scriptlets only in the presentation layer. What does he mean here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

柠檬心 2024-10-16 05:41:56

您似乎只专注于脚本的表示和流程控制部分,如使用 ifforswitch 语句和 out.print() 的东西。您似乎将 scriptlet 与 JSTL 进行了 1:1 比较。这是错误的。我并不是只谈论流程控制部分(它确实要被 JSTL 取代),而是谈论在 JSP 文件中编写原始 Java 代码。即收集请求参数、验证和转换值、与数据库和其他 Java 类/方法交互等。您通常(间接)在 Servlet 或 Filter 中执行的所有操作。

You seem to concentrate on only the presentation and flow-control part of the scriptlets as in using if, for and switch statements and out.print() things. You seem to compare scriptlets 1:1 with JSTL. This is wrong. I was not talking about the flow control part only (which is indeed to be replaced by JSTL), but about writing raw Java code in JSP files in general. I.e. gathering request parameters, validating and converting values, interacting with database and other Java classes/methods, etc. All things you normally (indirectly) do in a Servlet or Filter.

赴月观长安 2024-10-16 05:41:56

JSP 中不应该包含 scriptlet 代码。我推荐 100% JSTL 和零 scriplet 代码。

JSP 应该纯粹是演示。这就是仅使用 JSTL 编写 JSP 的隐藏好处,因为它们从其他地方获取所有动态数据。让服务层拥有业务逻辑并确定JSP需要什么数据。

这也回答了您的单元测试问题。您不必对 JSP 进行单元测试;这些将是类似 Selenium 的 UI 测试。如果逻辑位于服务层,那么如何测试它就很明显了。

JSP 不应该被继承。您当然可以使用 SiteMesh 之类的工具将它们组合在一起,但继承在您的 JSP 中不存在。一旦它们继承自Servlet,链就应该结束。

此外,这是一个错误的选择。两者都不需要重用、继承或单元测试。但这并不意味着没有明显的赢家:JSTL 是赢家。任何人都不应该在 JSP 中使用 scriptlet,除非是非常罕见的单行代码。 Scriptlet 正在自找麻烦。

如今,我更喜欢使用 Velocity 作为我的 Java Web UI 模板解决方案,而不是 JSP。只是我的意见。

You should not have scriptlet code in JSPs. I'd recommend 100% JSTL and zero scriplet code.

JSPs should be purely presentation. That's the hidden benefit of writing JSPs using only JSTL, because they get all their dynamic data elsewhere. Let the service layer have the business logic and determine what data the JSP needs.

This answers your unit testing question, too. You should not have to unit test JSPs; those would be Selenium-like UI tests. If the logic is in the service tier, it's obvious how you test it.

JSPs should not be inherited. You can certainly compose them together using something like SiteMesh, but inheritance has no part in your JSPs. Once they inherit from Servlet, the chain should be ended.

Besides, it's a false alternative. Neither one should require reuse, inheritance, or unit testing. But that doesn't mean there isn't a clear winner: it's JSTL. No one should be using scriptlets in JSPs, except for very rare one-liners. Scriptlets are begging for trouble.

These days I prefer Velocity as my web UI template solution for Java, much more than JSPs. Just my opinion.

厌倦 2024-10-16 05:41:56

我不能代表 BalusC,但总的来说,我相信他的想法是,这些事情应该由普通的 Java 代码来完成(如果您对整个 MVC 感兴趣,则在控制器和模型层中)。

  1. 您不能在单个级别上真正重用 JSP 标记,但您可以重用它们调用的类。

  2. JSTL 不能是抽象的,但普通的 Java 代码(您也许可以从 JSTL 调用)可以。

  3. 再说一次,你不能在 jstl 中有效地创建对象,但你可以在所有被调用的类中创建对象。

  4. JSTL 本身不可进行单元测试。但是您通过它调用的类和方法是。

I can't speak for BalusC but in general I believe he was getting at the idea that these kinds of things should be accomplished by your ordinary Java code (in the Controller and Model layers if you're into the whole MVC thing).

  1. You can't literally reuse JSP tags at an individual level, but you can reuse the classes they call into.

  2. JSTL can't be abstract, but ordinary Java code (which you can perhaps invoke from JSTL) can be.

  3. Again, you can't make objects usefully in jstl, but you can in all the classes that are called.

  4. JSTL by itself is not unit-testable. But the classes and methods you call through it are.

許願樹丅啲祈禱 2024-10-16 05:41:56

这取决于您使用的模式。通过使用MVCspring、struts、...),您应该避免在 JSP 中使用 scriptlet,因为它表示应该包含纯 XHTML 标记的视图。 JSTL 是一种声明性语言,某种 XML,而scriplet 不是。

特别是,我通过 prototype 使用 JSTL 与 AJAX 结合使用,无需生成 RIA实现另一种模式。最近我用 ExtJSDWR。就我而言,我发现有必要将 JSTL 和 scriplet 结合起来,在可能的情况下总是更喜欢 JSTL。

<!-- simple controller, each action is called by means of AJAX -->
<% String signExt="jpg"; %>
<% int r=0, iMaxRows=0, iMaxCols=0;%>
<c:choose>

    <c:when test="${param.action == 'get_chrequest_profile_table_by_family_and_date'}">
        <sql:query var="dataset">
            CALL GetProfilesView('<c:out value="${param.family_name}" />', '<c:out value="${param.reg_date}" />')
        </sql:query>

        <c:set var="strElements"><c:out value="${dataset.rowCount}" /></c:set> 
        <%  
        String strElements = pageContext.getAttribute("strElements").toString();
        int iElements = (int)Integer.valueOf(strElements).intValue(); 
        String to = "";
        %>

        <table class="tb_profiles" id="tb_profiles" iElements="<%=iElements%>"
               width="100%" frame=void border="0" cellPadding="0" cellSpacing="0" style="border-top: 3px solid gray; border-left: 1px solid gray">

            <%for(int i=1, j=0, col=0; i<100; i++){%>
            <tr>
                <%for(j=0; j<4; j++, col++){%>
                <c:set var="c" scope="page"><%=col%></c:set>

                <td name='<c:out value="${dataset.rows[c].chreqprofile_id}" />' >
                    <table width="100%" frame="below" cellPadding="0" cellSpacing="0"style="border-right: 1px solid gray;">

                        <%if( col < iElements){%>
                            <tr style="height:10mm">
                                <td class="td_function" style="cursor:default;">
                                    <c:out value="${dataset.rows[c].description}" />
                                </td>
                            </tr>
                            .................
                            <tr style="height:14mm">                        
                                <td class="td_signature" align="center" vAlign="middle">
                                    <img class="img_signature"
                                         src='../xdata/signatures/<c:out value="${dataset.rows[c].responsible_name}"/>.<%=signExt%>'
                                         alt='<c:out value="${dataset.rows[c].email}" />' 
                                    />
                                </td>
                            </tr>
                            .................

                            <c:set var="sMail"><c:out value="${dataset.rows[c].email}"/></c:set>
                            <% if( col < iElements-1){
                                    to = to + pageContext.getAttribute("sMail").toString() + ","; 
                               }else{
                                    to = to + pageContext.getAttribute("sMail").toString();
                               }
                            %>                      
                        <%}else{%>
                            <tr style="height:10mm">
                                <td class="td_function" style="cursor:default;">x</td>
                                .............
                            </tr>
                        <%}%>
                    </table>
                </td>               

                <%}%>
            </tr>
            <%
                if( col >= iElements){break;}
            }%>
        </table>
        <span id="span_mail_to" style="display:none;"><%=to%></span>        
    </c:when>   
    <c:when test="${param.action == 'functions_form_insert'}">  
        .............
    </c:when>   
</c:choose>

It depends on the pattern you're using. By using the MVC (spring, struts, ...) you should avoid the usage of scriptlets in your JSP, because it represent the view it should contain pure XHTML tags. JSTL is a declarative language some kind of XML, while scriplet isn't.

Particularly I have used JSTL in combination with AJAX via prototype for generating RIA without needing to implement another pattern. Recently I have seen this kind of programming with ExtJS and DWR. In my case I found It was necessary to combine both JSTL and scriplets always preferring JSTL when possible.

<!-- simple controller, each action is called by means of AJAX -->
<% String signExt="jpg"; %>
<% int r=0, iMaxRows=0, iMaxCols=0;%>
<c:choose>

    <c:when test="${param.action == 'get_chrequest_profile_table_by_family_and_date'}">
        <sql:query var="dataset">
            CALL GetProfilesView('<c:out value="${param.family_name}" />', '<c:out value="${param.reg_date}" />')
        </sql:query>

        <c:set var="strElements"><c:out value="${dataset.rowCount}" /></c:set> 
        <%  
        String strElements = pageContext.getAttribute("strElements").toString();
        int iElements = (int)Integer.valueOf(strElements).intValue(); 
        String to = "";
        %>

        <table class="tb_profiles" id="tb_profiles" iElements="<%=iElements%>"
               width="100%" frame=void border="0" cellPadding="0" cellSpacing="0" style="border-top: 3px solid gray; border-left: 1px solid gray">

            <%for(int i=1, j=0, col=0; i<100; i++){%>
            <tr>
                <%for(j=0; j<4; j++, col++){%>
                <c:set var="c" scope="page"><%=col%></c:set>

                <td name='<c:out value="${dataset.rows[c].chreqprofile_id}" />' >
                    <table width="100%" frame="below" cellPadding="0" cellSpacing="0"style="border-right: 1px solid gray;">

                        <%if( col < iElements){%>
                            <tr style="height:10mm">
                                <td class="td_function" style="cursor:default;">
                                    <c:out value="${dataset.rows[c].description}" />
                                </td>
                            </tr>
                            .................
                            <tr style="height:14mm">                        
                                <td class="td_signature" align="center" vAlign="middle">
                                    <img class="img_signature"
                                         src='../xdata/signatures/<c:out value="${dataset.rows[c].responsible_name}"/>.<%=signExt%>'
                                         alt='<c:out value="${dataset.rows[c].email}" />' 
                                    />
                                </td>
                            </tr>
                            .................

                            <c:set var="sMail"><c:out value="${dataset.rows[c].email}"/></c:set>
                            <% if( col < iElements-1){
                                    to = to + pageContext.getAttribute("sMail").toString() + ","; 
                               }else{
                                    to = to + pageContext.getAttribute("sMail").toString();
                               }
                            %>                      
                        <%}else{%>
                            <tr style="height:10mm">
                                <td class="td_function" style="cursor:default;">x</td>
                                .............
                            </tr>
                        <%}%>
                    </table>
                </td>               

                <%}%>
            </tr>
            <%
                if( col >= iElements){break;}
            }%>
        </table>
        <span id="span_mail_to" style="display:none;"><%=to%></span>        
    </c:when>   
    <c:when test="${param.action == 'functions_form_insert'}">  
        .............
    </c:when>   
</c:choose>
原谅我要高飞 2024-10-16 05:41:56

我不认为 scriplets 太糟糕了,特别是如果您遵循其中的设计模式,我在 spring mvc 上做了很多工作,在我的 jsp 中,我只是在 scriplits 中获取模型数据,然后在 html 中使用简单的 java 代码将其显示给用户,我觉得它比JSTL给了我更多的自由。

I dont see that scriplets is too bad specially if you follows design pattern in it, I work a lot on spring mvc, in my jsp i just get the model data in scriplits, and i show it to the user using simple java code in html, i feel it give me more freedom than JSTL.

只涨不跌 2024-10-16 05:41:56

下面是一个比较 JSP 和 Facelets 的表格,可能对某个地方的某人有帮助:


来源

Here is a table comparing JSP and Facelets that may possibly be helpful to someone, somewhere:


Source

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文