38

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?

Community
  • 1
  • 1
palAlaa
  • 9,500
  • 33
  • 107
  • 166

6 Answers6

17

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.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • 5
    from now on, pure java code in servlets , filters and context listener only and JSTL in JSPs. – palAlaa Dec 27 '10 at 08:02
14

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.

Makoto
  • 104,088
  • 27
  • 192
  • 230
duffymo
  • 305,152
  • 44
  • 369
  • 561
  • I totally agree that we should use JSTL in JSPs,do u mean with service layer a controller layer? – palAlaa Dec 26 '10 at 21:35
  • controller layer is part of view; you need a service layer as well. – duffymo Dec 26 '10 at 22:02
  • That means the controller centralizes the logic for dispatching requests to the next view, so the controller is the servlet in servlet-JSP development, and the service layer is the parts that provide specific service in servlet. Am I correct? – palAlaa Dec 26 '10 at 22:35
  • It doesn't have to be. Most web MVC frameworks have a front controller servlet that defers to POJO controller classes. I'd argue that the servlet shouldn't be the controller. – duffymo Dec 26 '10 at 23:24
4

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.

Dan
  • 10,990
  • 7
  • 51
  • 80
  • 1
    The point is that if you write a bunch of Java code in your JSP, you can't extend the classes you crete there, reuse them, write unit tests for them etc. Of course, if you use scriptlets for nothing more than <%=%> and the occasional <% if () { %> then perhaps it's not as relevant. – Dan Dec 26 '10 at 22:36
  • JSP makes Code look Elegant, XML like , declarative like not Procedural Though it does not make code Testable, Reusable per se, but its still better because Java Code is not INLINED and it gets rid of java constructs and Syntax - Its about enhancing readability. – Karan Kaw Mar 01 '17 at 11:44
2

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.

Alaa Abuzaghleh
  • 1,023
  • 6
  • 11
2

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>
ArBR
  • 4,032
  • 2
  • 23
  • 29
  • 8
    No offence but that code looks like a horrible mish mash of jstl, scriptlets and html. – Gerard Feb 07 '11 at 11:05
  • 1
    @Gearoid: This code allows you easily implement pure JSTL web-applications. You're right in the sense that this is a mixture of JSTL, scriptlet and HTML. This is some kind of controller that serves HTML to the client, this code should be called via AJAX and rendered on the DOM via javascript. As I have told if your primary concern is the code quality you should use some MVC-framework such as SPRING... – ArBR Feb 08 '11 at 18:34
0

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

Source

Yster
  • 3,147
  • 5
  • 32
  • 48