JSPファイルでJavaコードを回避する方法


1673

私はJava EEを初めて使用し、次の3行のようなものを知っています

<%= x+1 %>
<%= request.getParameter("name") %>
<%! counter++; %>

は昔ながらのコーディング方法であり、JSPバージョン2には、JSPファイルでJavaコードを回避する方法が存在します。誰かが代替のJSP 2行を教えてもらえますか?このテクニックは何と呼ばれていますか?


22
@Koray Tugay、カウンター変数がその使用前にどこかで宣言されている限り、最も確実に有効です...
シェルドンR.

@SheldonR。これは有効です:<%= counter ++%>またはこれ:<%!intカウンタ= 0; int x = counter ++; %>ではなく、<%!intカウンタ= 0; カウンター++; %>
Koray Tugay 2017年

@KorayTugay、私が意味したことは、変数カウンターが前のスクリプトブロックで宣言された場合、それは後のブロックで有効になるはずです。しかし結局のところ、最近のJ2EEプログラマーはとにかく、スクリプトレットの代わりにEL変数を使用する必要があります...
Sheldon R.

回答:


1972

使用スクリプトレット(それらの<% %>中のもの)JSPは、確かに非常にの誕生以来推奨されてタグライブラリ(のようなJSTL)とEL式言語、それらの${}2001年のもの)ウェイ・バック。

スクリプトレットの主な欠点は次のとおりです。

  1. 再利用性:スクリプトレットを再利用することはできません。
  2. 置き換え可能性:スクリプトレットを抽象化することはできません。
  3. オブジェクト指向の機能:継承/構成を利用することはできません。
  4. デバッグ可能性:スクリプトレットが途中で例外をスローした場合、取得できるのは空白のページだけです。
  5. テスト容易性:スクリプトレットは単体テストできません。
  6. 保守性:サルドごとに、混合/雑然とした/重複したコードロジックを維持するためにより多くの時間が必要です。

Sun Oracle自体も、JSPコーディング規約で、(タグ)クラスによって同じ機能が可能である場合は常にスクリプトレットの使用を避けることを推奨しています。いくつかの関連する引用がここにあります:

JSP 1.2仕様から、JSP標準タグライブラリ(JSTL)をWebアプリケーションで使用して、ページ内のJSPスクリプトレットの必要性を減らすことを強くお勧めします。JSTLを使用するページは、一般に、読みやすく、保守も簡単です。

...

タグライブラリが同等の機能を提供する場合は常に、JSPスクリプトレットを避けてください。これにより、ページが読みやすくなり、保守が容易になり、ビジネスロジックをプレゼンテーションロジックから分離しやすくなり、ページがJSP 2.0スタイルのページに進化しやすくなります(JSP 2.0仕様では、スクリプトレットの使用はサポートされていますが、それほど重視されていません)。

...

ビジネスロジックからのプレゼンテーション層の間の結合を減らすためにモデルビューコントローラー(MVC)設計パターンを採用するという精神で、JSPスクリプトレットをビジネスロジックの記述に使用ないでください。むしろ、JSPスクリプトレットは、クライアントの要求の処理から返されたデータ(「値オブジェクト」とも呼ばれます)を適切なクライアント対応の形式に変換する必要がある場合に使用されます。それでも、これはフロントコントローラーサーブレットまたはカスタムタグを使用する方が適切です。


スクリプトレットを置き換える方法は、コード/ロジックの唯一の目的によって異なります。多くの場合、このコードは十分に価値のあるJavaクラスに配置されます。

  • すべてのリクエストで同じ Javaコードを呼び出したい場合は、リクエストされたページに関係なく、たとえばユーザーがログインしているかどうかを確認した後、フィルターを実装し、それに応じてコードをメソッドに記述します。例えば:doFilter()

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
        if (((HttpServletRequest) request).getSession().getAttribute("user") == null) {
            ((HttpServletResponse) response).sendRedirect("login"); // Not logged in, redirect to login page.
        } else {
            chain.doFilter(request, response); // Logged in, just continue request.
        }
    }

    <url-pattern>対象となるJSPページをカバーする適切な場所にマッピングする場合、JSPページ全体に同じコードをコピーアンドペーストする必要はありません。


  • いくつかのJavaコードを呼び出してリクエストを前処理する場合、たとえば、必要に応じてクエリパラメータに基づいてデータベースからリストをプリロードしてテーブルに表示する場合は、サーブレットを実装し、それに応じてコードをdoGet()メソッドに記述します。例えば:

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            List<Product> products = productService.list(); // Obtain all products.
            request.setAttribute("products", products); // Store products in request scope.
            request.getRequestDispatcher("/WEB-INF/products.jsp").forward(request, response); // Forward to JSP page to display them in a HTML table.
        } catch (SQLException e) {
            throw new ServletException("Retrieving products failed!", e);
        }
    }

    この方法で例外を処理する方が簡単です。DBは、JSPレンダリングの最中ではなく、JSPが表示されるずっと前にアクセスされます。DBアクセスが例外をスローするたびに、応答を変更する可能性があります。上記の例では、デフォルトのエラー500ページが表示され、とにかく<error-page>inでカスタマイズできますweb.xml


  • フォーム送信の処理など、Javaコードを呼び出してリクエストを後処理する場合は、サーブレットを実装し、それに応じてdoPost()メソッドにコードを記述します。例えば:

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        User user = userService.find(username, password);
    
        if (user != null) {
            request.getSession().setAttribute("user", user); // Login user.
            response.sendRedirect("home"); // Redirect to home page.
        } else {
            request.setAttribute("message", "Unknown username/password. Please retry."); // Store error message in request scope.
            request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); // Forward to JSP page to redisplay login form with error.
        }
    }

    このようにすると、さまざまな結果ページの宛先を簡単に処理できます。エラーが発生した場合は検証エラーを含むフォームを再表示し(この特定の例では${message}ELを使用してフォームを再表示できます)、成功した場合は目的のターゲットページに移動します。


  • Javaコードを呼び出して、実行プランやリクエストとレスポンスの宛先を制御する場合は、MVCのフロントコントローラーパターンに従ってサーブレットを実装します。例えば:

    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            Action action = ActionFactory.getAction(request);
            String view = action.execute(request, response);
    
            if (view.equals(request.getPathInfo().substring(1)) {
                request.getRequestDispatcher("/WEB-INF/" + view + ".jsp").forward(request, response);
            } else {
                response.sendRedirect(view);
            }
        } catch (Exception e) {
            throw new ServletException("Executing action failed.", e);
        }
    }

    または、JSFSpring MVCWicketなどのMVCフレームワークを採用するだけで、カスタムサーブレットを必要とせずに、JSP / FaceletsページとJavaBeanクラスのみを使用できます。


  • JSPページ内のフロー制御する Javaコードを呼び出す場合は、JSTLコアのような(既存の)フロー制御taglibを取得する必要があります。たとえばList<Product>、テーブルに表示する:

    <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
    ...
    <table>
        <c:forEach items="${products}" var="product">
            <tr>
                <td>${product.name}</td>
                <td>${product.description}</td>
                <td>${product.price}</td>
            </tr>
        </c:forEach>
    </table>

    すべてのHTMLの中にうまく収まるXMLスタイルのタグを使用すると、コードは、さまざまな開き括弧と閉じ括弧を備えた一連のスクリプトレットよりも読みやすく(したがって、保守性が向上します)(「この終了括弧はどこに属しているのですか?」)。次のコードをに追加することにより、スクリプトレットがまだ使用されている場合は常に例外をスローするようにWebアプリケーションを構成するのが簡単ですweb.xml

    <jsp-config>
        <jsp-property-group>
            <url-pattern>*.jsp</url-pattern>
            <scripting-invalid>true</scripting-invalid>
        </jsp-property-group>
    </jsp-config>

    Facelets、ジャワEEの一部であるJSPの後継は、MVCフレームワーク提供JSFを、すでに、しない使用することができるスクリプトレットを。この方法では、自動的に「正しい方法」で物事を実行する必要があります。


  • JSPページ内の「バックエンド」データにアクセスして表示するためにJavaコードを呼び出す場合は、EL(式言語)を使用する必要があります${}。たとえば、送信された入力値を再表示します。

    <input type="text" name="foo" value="${param.foo}" />

    ${param.foo}結果が表示されますrequest.getParameter("foo")


  • いくつかのユーティリティ JavaコードをJSPページ(通常はpublic staticメソッド)で直接呼び出す場合は、それらをEL関数として定義する必要があります。JSTLには標準の関数taglibがありますが関数を自分で簡単に作成することもできますXSS 攻撃fn:escapeXmlを防ぐためにJSTL がどのように役立つかの例を次に示します。

    <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
    ...
    <input type="text" name="foo" value="${fn:escapeXml(param.foo)}" />

    XSSの感度は、特にJava / JSP / JSTL / EL /に特に関連しているわけではないことに注意してください。この問題は、開発するすべての Webアプリケーションで考慮する必要があります。スクリプトレットの問題は、少なくとも標準のJava APIを使用せずに、組み込みの防止手段を提供しないことです。JSPの後継であるFaceletsにはすでに暗黙のHTMLエスケープ機能があるので、FaceletsのXSSホールについて心配する必要はありません。

以下も参照してください。


117
+1すばらしい答え。しかし、独断的に行かないでください。スクリプトレットを使用してもかまいませんが、それはルールを証明する例外であるべきです。
svachon

26
@svachon:スクリプトレットは、迅速なプロトタイピング/テストに役立ちます。私の知る限りでは、つまりスクリプトレットの唯一の「正当な」生産使用、あります<% response.getWriter().flush(); %></head><body>ウェブブラウザでのWebページの解析性能を向上させるためには。ただし、サーバー側の出力バッファーサイズが小さい場合(1〜2KB)、この使用はまったく無視できます。こちらの記事もご覧ください
BalusC 2010

5
@BalusCゲッター/セッターのパターンに従わないJavaクラスに数回悩まされてきました。私見それはscripltetが仕事をする場合です。
svachon 2010

41
@svachon:これらのクラスを独自のjavabeanクラスでラップし、代わりに使用します。
BalusC 2010

31
これはかなり良い答えでしたが、doGetとdoPostの部分は誤解を招くものです。これらのメソッドは、特定の要求(HEAD、GET、POST)メソッドを処理するためのものであり、「前処理」または「後処理」要求用ではありません。
MetroidFan2002 2012

225

安全対策として:スクリプトレットを永久に無効にする

別の質問を検討している、あなたは、常に自分の中でスクリプトレットを無効にする必要がありますすることができweb.xml、Webアプリケーション記述子。

開発者がスクリプトレットを追加するのを防ぐために、特に遅かれ早かれ概要を失う大企業では、私は常にそうするつもりです。web.xml設定は次のようになります。

<jsp-config>
  <jsp-property-group>
    <url-pattern>*.jsp</url-pattern>
     <scripting-invalid>true</scripting-invalid>
  </jsp-property-group>
</jsp-config>

4
これにより、スクリプトレットのコメントも無効になりますか?:<%-- comment that i don't want in the final HTML --%>。HTMLコメントではなく、これらのコメントを使用すると便利です。
デビッドラベンダー

16
@MrSpoonが答えを追跡しました。この回答+コメントに従って、これ<% %>によりスクリプトレット、スクリプトレット式<%! %>、およびスクリプトレット宣言がオフになり<%= %>ます。つまり、ディレクティブ<%@ %>とコメント<%-- --%>は引き続き有効で使用可能であるため、コメントやインクルードを実行できます。
Martin Carney、2015

3
スクリプトレットディレクティブの無効化はひどいものになります。余白を増やしてレガシーシステムを操作する場合、余白のトリミングは非常に重要です。
corsiKa

108

JSTLは、条件、ループ、セット、取得などのタグを提供します。次に例を示します。

<c:if test="${someAttribute == 'something'}">
   ...
</c:if>

JSTLはリクエスト属性で動作します-それらは、ほとんどの場合、JSPに転送するサーブレットによってリクエストで設定されます。


2
JSTLがリクエスト属性で機能するのはなぜですか?それらはどのスコープの属性でも機能しますね。
Koray Tugay 14

60

これが正しいかどうかはわかりません。

あなたはMVCについて何かを読むべきです。Spring MVCStruts 2は、最も一般的な2つのソリューションです。


29
MVCは、SpringまたはStrutsを使用せずに、上記のテクニックの多くを使用してサーブレット/ jspで実装できます。
ステパニアン

18
それはどのように質問に答えますか?
xyz

54

JSTLタグをEL式と一緒に使用して、JavaコードとHTMLコードの混在を回避できます。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
<html>
    <head>
    </head>
    <body>

        <c:out value="${x + 1}" />
        <c:out value="${param.name}" />
        // and so on

    </body>
</html>

34

また、多くのHTMLを生成するWicketなどのコンポーネントベースのフレームワークもあります。HTMLで終わるタグは非常に基本的であり、実際に混合されるロジックはありません。結果は、典型的なHTML要素を持つほとんど空のようなHTMLページです。欠点は、Wicket APIには学ぶべき多くのコンポーネントがあり、これらの制約の下ではいくつかのことを達成することが難しい場合があることです。


33

MVCアーキテクチャパターンでは、JSPはビューレイヤーを表します。JSPにJavaコードを埋め込むことは悪い習慣と考えられています。JSTLfreeMarkerベロシティをJSPで「テンプレートエンジン」として使用できます。これらのタグのデータプロバイダーは、処理しているフレームワークによって異なります。Struts 2そして、webworkMVCパターンの実装として使用していますOGNL「JSPに豆のプロパティを公開するために非常に興味深い技術を」。


27

経験上、JSPにはいくつかの欠点があることが示されています。その1つは、マークアップと実際のコードの混合を避けるのが難しいことです。

可能であれば、必要な作業に特化したテクノロジーの使用を検討してください。Java EE 6にはJSF 2.0があり、この方法でJava BeanをJSFページと接着するなど、多くの優れた機能を提供します#{bean.method(argument)}


3
古い答えですが、JSFはJava空間で最も恐ろしい発明の1つであると言うのは仕方がありません。単一の(HTTP GETのような)リンクを作成してみてください。その理由が理解できます。
Alex

@アレックスが、それでも良い。さらに良いものをお勧めします。
するThorbjörnRavnアンデルセン

26

JSPでのJavaコーディングの欠点を単に回避したい場合は、スクリプトレットを使用しても可能です。JSPで最小限のJavaを使用し、JSPページで計算とロジックをほとんど使用しないように、いくつかの規則に従ってください。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%//instantiate a JSP controller
MyController clr = new MyController(request, response);

//process action if any
clr.process(request);

//process page forwaring if necessary

//do all variable assignment here
String showMe = clr.getShowMe();%>

<html>
    <head>
    </head>
    <body>
        <form name="frm1">
            <p><%= showMe %>
            <p><% for(String str : clr.listOfStrings()) { %>
            <p><%= str %><% } %>

            // and so on   
        </form>
    </body>
</html>

26

JSTLを使用して独自のタグをカスタマイズおよび作成する方法を学ぶ

ELであることに注意(実行時例外、リファクタリング)
Wicketのは、あまりにも(パフォーマンス、小さなアプリケーションや簡単なビュー階層のためtoilsome)悪かもしれ

から例java2s

これは、Webアプリケーションのweb.xmlに追加する必要があります

<taglib>
    <taglib-uri>/java2s</taglib-uri>
    <taglib-location>/WEB-INF/java2s.tld</taglib-location>
</taglib>

/ WEB-INF /にFile:java2s.tldを作成します。

<!DOCTYPE taglib
  PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
   "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<!-- a tab library descriptor -->
<taglib xmlns="http://java.sun.com/JSP/TagLibraryDescriptor">
    <tlib-version>1.0</tlib-version>
    <jsp-version>1.2</jsp-version>
    <short-name>Java2s Simple Tags</short-name>

    <!-- this tag manipulates its body content by converting it to upper case
    -->
    <tag>
        <name>bodyContentTag</name>
        <tag-class>com.java2s.BodyContentTag</tag-class>
        <body-content>JSP</body-content>
        <attribute>
          <name>howMany</name>
        </attribute>
    </tag>
</taglib>

次のコードをWEB-INF \ classes \ com \ java2sにコンパイルします

package com.java2s;

import java.io.IOException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyContent;
import javax.servlet.jsp.tagext.BodyTagSupport;

public class BodyContentTag extends BodyTagSupport{
    private int iterations, howMany;

    public void setHowMany(int i){
        this.howMany = i;
    }

    public void setBodyContent(BodyContent bc){
        super.setBodyContent(bc);
        System.out.println("BodyContent = '" + bc.getString() + "'");
    }

    public int doAfterBody(){
        try{    
            BodyContent bodyContent = super.getBodyContent();
            String bodyString  = bodyContent.getString();
            JspWriter out = bodyContent.getEnclosingWriter();

            if ( iterations % 2 == 0 ) 
                out.print(bodyString.toLowerCase());
            else
                out.print(bodyString.toUpperCase());

            iterations++;
            bodyContent.clear(); // empty buffer for next evaluation
        }
        catch (IOException e) {
            System.out.println("Error in BodyContentTag.doAfterBody()" + e.getMessage());
            e.printStackTrace();
        } // end of catch

        int retValue = SKIP_BODY;

        if ( iterations < howMany ) 
            retValue = EVAL_BODY_AGAIN;

        return retValue;
    }
}

サーバーを起動し、bodyContent.jspをブラウザーにロードします

<%@ taglib uri="/java2s" prefix="java2s" %>
<html>
    <head>
        <title>A custom tag: body content</title>
    </head>
    <body>
        This page uses a custom tag manipulates its body content.Here is its output:
        <ol>
            <java2s:bodyContentTag howMany="3">
            <li>java2s.com</li>
            </java2s:bodyContentTag>
        </ol>
    </body>
</html>

コンポーネントの再利用は問題ありませんが、一部のフィールドを対象としています
tomasb '20

25

Wicketは、javaをhtmlから完全に分離する代替手段でもあるため、設計者とプログラマーは、お互いをほとんど理解せずに、一緒に、異なるコードセットで作業できます。

Wicketを見てください。


23

あなたは良い質問をし、良い答えを得ましたが、JSPを取り除くことをお勧めします。それは最終的には死ぬ時代遅れの技術です。テンプレートエンジンのような最新のアプローチを使用します。ビジネスレイヤーとプレゼンテーションレイヤーが非常に明確に分離され、テンプレートにJavaコードがないため、ほとんどの場合WYSIWYGを利用して、Webプレゼンテーション編集ソフトウェアから直接テンプレートを生成できます。

また、フィルターや前処理と後処理は絶対に避けてください。そうしないと、変数がどこで値を取得するかが常にわからないため、サポートやデバッグの問題に対処できます。


9
JSPはそれ自体がテンプレートエンジンです
WarFox 2011

1
-1- フィルター、プリプロセッサー、ポストプロセッサーを使用する完全に正当な理由はたくさんあります。ええ、あなたは不思議に思える価値観に終わる可能性がありますが、アーキテクチャを理解していなければできません。
RustyTheBoyRobot

21

JSPファイル内のJavaコードを回避するために、JavaはJSTLのようなタグライブラリを提供します。また、Javaは、すべてのプログラミング構造をタグの形式で書き込むことができるJSFを考案しました。


21

どんなに避けようとも、他の開発者と共同で作業する場合、一部の開発者はスクリプトレットを優先して、邪悪なコードをプロジェクトに挿入します。したがって、スクリプトレットのコードを削減したい場合は、最初のサインでプロジェクトを設定することが非常に重要です。これを乗り越えるテクニックはいくつかあります(他のフレームワークを含む)。ただし、純粋なJSPを使用する場合は、JSTLタグファイルを使用します。これの良い点は、プロジェクトのマスターページを設定して、他のページがマスターページを継承できることです。

次のコンテンツを含むWEB-INF / tagsの下にbase.tagというマスターページを作成します。

<%@tag description="Overall Page template" pageEncoding="UTF-8"%>

<%@attribute name="title" fragment="true" %>

<html>
  <head>
    <title>  
       <jsp:invoke fragment="title"></jsp:invoke>
    </title>

  </head>
  <body>
    <div id="page-header">
       ....
    </div>
    <div id="page-body">
      <jsp:doBody/>
    </div>
    <div id="page-footer">
      .....
    </div>
  </body>
</html>

このページでは、「タイトル」というフラグメントを作成しました。これにより、子ページで、マスターページのこの場所にさらにコードを挿入できます。また、タグ<jsp:doBody/>は子ページのコンテンツに置き換えられます

WebContentフォルダーに子ページ(child.jsp)を作成します。

<%@ taglib prefix="t" tagdir="/WEB-INF/tags" %>

<t:base>
    <jsp:attribute name="title"> 
        <bean:message key="hello.world" />
    </jsp:attribute>

    <jsp:body>
    [Put your content of the child here]
    </jsp:body>   
</t:base>

<t:base>は、使用するマスターページ(現時点ではbase.tag)を指定するために使用されます。<jsp:body>ここのタグ内のすべてのコンテンツが<jsp:doBody/>マスターページのを置き換えます。子ページには任意のタグlibを含めることもでき、通常は他のタグと同じように使用できます。ただし、ここでスクリプトレットコード(<%= request.getParameter("name") %>...)を使用してこのページを実行しようとすると、が表示されますJasperException because Scripting elements ( &lt;%!, &lt;jsp:declaration, &lt;%=, &lt;jsp:expression, &lt;%, &lt;jsp:scriptlet ) are disallowed here。したがって、他の人が邪悪なコードをjspファイルに含める方法はありません

コントローラからこのページを呼び出す:

コントローラーから簡単にchild.jspファイルを呼び出すことができます。これはStrutsフレームワークでもうまく機能します


「どんなに避けようとしても、他の開発者と一緒に作業するとき、一部の開発者は依然としてスクリプトレットを好み、悪意のあるコードをプロジェクトに挿入します。」「安全策として:スクリプトレットを無効にする」の回答を参照してください。
Lluis Martinez



17

誰かが実際に複数の言語でのプログラミングに反対している場合は、GWTをお勧めします。理論的には、すべてのJS要素とHTML要素を回避できます。GoogleToolkitはすべてのクライアントと共有コードをJSに変換するため、問題は発生しません。あなたは他の言語でコーディングせずにウェブサービスを持っています。拡張機能(smartGWTまたはVaadin)によって提供されるため、どこからでもデフォルトのCSSを使用できます。何十ものアノテーションを学ぶ必要はありません。

もちろん、必要に応じて、コードの奥深くにハックしてJSを挿入し、HTMLページを充実させることができますが、実際には、必要に応じてそれを回避することができ、他のフレームワークで作成されたとおりの結果が得られます。私は試してみる価値があると言い、基本的なGWTは十分に文書化されています。

そしてもちろん、多くの仲間のプログラマーはここに他のいくつかの解決策を説明または推奨しました。GWTは、Webパーツを実際に処理したり最小限にしたりしたくない人のためのものです。


1
OPの質問には実際には答えません。
エヴァンDonovan 14

1
@EvanDonovanよく、実際にはそれは答えを与えます。Javaコードを他の言語と混同する必要はありません。コーディングにJavaを使用していますが、Java呼び出しなしでJSに変換されます。しかし、問題の範囲は、古典的なJSPの混乱を回避する方法です。そして、GWTテクノロジーがそれを解決します。この回答は誰も言及していないので追加しましたが、JSPの代替であるため、適切です。私は質問の全範囲に答えるのではなく、選択肢を探している人々に貴重な情報を追加したいと思いました。
CsBalazsHungary 14

16

Pythonの世界からのすばらしいアイデアは、テンプレート属性言語です。TALはZope(したがって「Zopeページテンプレート」、ZPTとも呼ばれます)によって導入された標準であり、PHP、XSLT、Javaでも実装されています(Python / ZopeおよびPHPインカネーションを使用しました)。このテンプレート言語のクラスでは、上記の例は次のようになります。

<table>
    <tr tal:repeat="product products">
        <td tal:content="product/name">Example product</td>
        <td tal:content="product/description">A nice description</td>
        <td tal:content="product/price">1.23</td>
    </tr>
</table>

コードは、通常のHTML(またはXHTML)に加えて、XML名前空間のいくつかの特別な属性に似ています。ブラウザで表示でき、設計者が安全に微調整できます。マクロとi18nのサポートもあります:

<h1 i18n:translate="">Our special offers</h1>
<table>
    <tr tal:repeat="product products">
        <td tal:content="product/name"
            i18n:translate="">Example product</td>
        <td tal:content="product/description"
            i18n:translate="">A nice description</td>
        <td tal:content="product/price">1.23</td>
    </tr>
</table>

コンテンツの翻訳が利用可能な場合、それらが使用されます。

ただし、Javaの実装についてはあまり知りません。


1
JSPは2009年12月以降、この機能をサポートするFaceletsに成功しています。FaceletsもXMLベースです。特に、Java EE 6チュートリアルのFaceletsの章ui:xxxFacelts VDLのタグも参照してください。
BalusC 2012年

Faceletsについてはよく知りませんが、IIRCでは、カスタムXML要素を実装するクラスを作成することがすべてです。TAL / ZPTの方法は、元の要素を埋めるまたは置き換える特別な属性を持つ真の(X)HTMLを含むテンプレートを持つことです。したがって、作業用テンプレートを表示して、素敵なダミーコンテンツのプロトタイプを見ることができます。Faceletsがカスタム属性を使用して(追加の名前空間なしで)元のHTML要素を微調整できるかどうかはわかりません。
トビアス

私はこのFaceletsのものをもう一度見ました。あらゆる検証機能などが含まれているため、TALとはまったく異なる哲学に従っています。TALの方法は、「テンプレートからロジックをできるだけきれいに保ちます。それを供給するコントローラによってすべての複雑なことを実行させる」です。Faceletsテンプレートをデザイナーに渡して、彼/彼女に微調整してもらうことは決してありません。それは不可能です。生成されたコンテンツについて-それはtal:replace="structure (expression)"いつも属性を使用するのと同じです。
トビアス


14

確かに、<%! counter++; %>イベントプロデューサー/コンシューマーアーキテクチャーに置き換えてください。カウンターをインクリメントする必要があることをビジネスレイヤーに通知すると、カウンターはそれに応じて反応し、プレゼンターに通知してビューを更新します。多くのデータベーストランザクションが関係しています。将来的には、カウンターの新しい値と古い値を知っておく必要があるためです。明らかに層が完全に切り離されているため、シリアライゼーションが関係しています。RMI、IIOP、SOAPを介してカウンターをインクリメントできます。ただし、HTMLのみが必要であり、実装する必要はありません。これは、ありふれたケースであるためです。新しい目標は、新しい光沢のあるE7、64GB RAMサーバーで1秒あたり250の増分に到達することです。

私はプログラミングに20年以上携わっていますが、ほとんどのプロジェクトはセクステットの前に失敗します。他のプロジェクトは、機能性のみに関心がある人々によって運営され、非常に成功しました。また、プロジェクトの早い段階で実装された硬いオブジェクト構造は、仕様の大幅な変更(別名アジャイル)にコードを適合させることができなくなります。

そのため、プロジェクトの初期または特に必要がない場合に、「レイヤー」または冗長データ構造を定義するアクティビティを先延ばしと見なします。  


11

技術的には、JSPは実行時にすべてサーブレットに変換されます。JSPは、MVCパターンに従って、ビジネスロジックと設計ロジックを分離する目的で最初に作成されました。したがって、JSPは技術的には実行時のすべてのJavaコードです。しかし、質問に答えるために、タグライブラリは通常、JSPページにロジックを適用する(Javaコードを削除する)ために使用されます。


8

Java Webアプリケーションで次のものを使用すると、JSPのフォアグラウンドからJavaコードを削除できます。

  1. WebアプリケーションにMVCアーキテクチャを使用する

  2. JSPタグを使用する

    a。標準タグ

    b。カスタムタグ

  3. 式言語


8

JSPファイルでJavaコードを回避する方法

式言語(EL)に加えて、JSTLのようなタブライブラリタグを使用できます。しかし、ELはJSPではうまく機能しません。そのため、JSPを完全に削除し、Faceletsを使用する方が良いでしょう。

Faceletsは、JSF(Java Server Faces)用に設計された最初の非JSPページ宣言言語であり、JSP開発者に、JSPと比較してよりシンプルで強力なプログラミングモデルを提供します。Webアプリケーション開発用のJSPで発生するさまざまな問題を解決します。

ここに画像の説明を入力してください

ソース


私は間違いなくこの応答を2番目にします。FaceletsありまたはなしのJSF。JSPでの開発は、10年以上前に大体終わったと思いました。私は最後に2000年にJSPを書きました!
キャベッジ

4

スクリプトレットの使用は非常に古い方法であり、推奨されません。JSPページに何かを直接出力する場合は 、JSTLとともに式言語(EL)を使用します。

Velocity、Freemarker、Thymeleafなどのテンプレートエンジンを使用するなど、他のオプションもあります。しかし、ELとJSTLでプレーンJSPを使用すると、ほとんどの場合私の目的に役立ち、初心者にとっても最も簡単なようです。

また、ビューレイヤーでビジネスロジックを実行することはベストプラクティスではないことに注意してください。サービスレイヤーでビジネスロジックを実行し、コントローラーを介して出力結果をビューに渡す必要があります。


3

私の友人はこれ以上何も使用していません。私のアドバイスは、ビュー(css、html、javascriptなど)をサーバーから切り離すことです。

私の場合、システムはAngularでビューを処理し、必要なデータはすべてRESTサービスを使用してサーバーから取得されます。

私を信じて、これはあなたのデザイン方法を変えるでしょう


3

UIデザインにjavascriptフレームワークのようなバックボーンを使用し、Rest APIを使用してデータをフェッチします。これにより、UIからjava依存関係が完全に削除されます。


3

JSP 2.0には「タグファイル」と呼ばれる機能があり、外部javaコードなしでタグを記述できますtld。あなたは、作成する必要がある.tagファイルをして、それを入れてWEB-INF\tagsも、あなたのタグをパッケージ化するためのディレクトリ構造を作成することができます。

例えば:

/WEB-INF/tags/html/label.tag

<%@tag description="Rensders a label with required css class" pageEncoding="UTF-8"%>
<%@attribute name="name" required="true" description="The label"%>

<label class="control-label control-default"  id="${name}Label">${name}</label>

好きに使う

<%@ taglib prefix="h" tagdir="/WEB-INF/tags/html"%>
<h:label  name="customer name" />

また、タグ本体が簡単に読み取れます

/WEB-INF/tags/html/bold.tag
<%@tag description="Bold tag" pageEncoding="UTF-8"%>
<b>
  <jsp:doBody/>
</b>

これを使って

<%@ taglib prefix="h" tagdir="/WEB-INF/tags/bold"%>
<h:bold>Make me bold</h:bold>

サンプルは非常に単純ですが、ここでは多くの複雑なタスクを実行できます。あなたが他のタグを使用することができます考慮してください。(例JSTLのようなタグを制御しているif/forEcah/chosenようなテキスト操作format/contains/uppercase、あるいはSQLタグをselect/update例えば、すべての種類のパラメータを渡す、) Hashmap、アクセスsessionrequest、...あなたのタグファイルで、あまりにも。

タグファイル は、JSPファイルのようにタグを変更するときにサーバーを再起動する必要がなかったため、簡単に開発できます。これにより、開発が容易になります。

優れたタグがたくさんあるStruts 2のようなフレームワークを使用していても、独自のタグを使用するとコードを大幅に削減できる場合があります。タグパラメータをStrutsに渡して、フレームワークタグをカスタマイズできます。

タグを使用すると、Javaを回避するだけでなく、HTMLコードを最小限に抑えることができます。私は自分のページでコードの重複が始まるのを見てすぐに、HTMLコードを確認してタグを作成しようとしています。

(JSPコードでJavaを使用することになったとしても、そうではないと思いますが、そのコードをタグにカプセル化できます)


1

多くの回答が言うように、JSTLを使用するか、独自のカスタムタグを作成します。カスタムタグの作成についての良い説明はここにあります


1
  1. サーブレットクラス内に値とパラメーターを作成する
  2. JSTL / Taglibを使用して、JSP内でこれらの値とパラメーターをフェッチします。

このアプローチの良い点は、コードもHTMLのようなコードであることです。


0

JSTLタグをEL式と一緒に使用すると、これを回避できます。jspページに次のものを配置します。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.