JSP 파일에서 Java 코드를 피하는 방법은 무엇입니까?


1673

Java EE를 처음 사용하고 다음 세 줄과 같은 것을 알고 있습니다.

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

JSP 버전 2에는 JSP 파일에서 Java 코드를 피하는 방법이 있습니다. 다른 JSP 2 라인을 알려주시겠습니까?


22
@Koray Tugay, 카운터 변수가 사용되기 전에 어딘가에 선언되면 가장 확실합니다 ...
Sheldon R.

@SheldonR. 이것은 유효합니다 : <% = counter ++ %> 또는 이것 : <%! 정수 카운터 = 0; int x = 카운터 ++; %>는 아니지만 <%! 정수 카운터 = 0; 카운터 ++; %>
Koray Tugay

@KorayTugay, 변수 카운터가 이전 스크립트 블록에서 선언 된 경우 나중에 블록에서 유효해야합니다. 그러나 궁극적으로 오늘날 J2EE 프로그래머는 어쨌든 스크립틀릿 대신 EL 변수를 사용해야합니다.
Sheldon R.

답변:


1971

의 사용 스크립틀릿 (사람 <% %>의 일) JSP는 실제로 매우의 탄생 있기 때문에 권장하지 않습니다 태그 라이브러리 (같은 JSTL 과) EL ( 표현 언어 , 그 ${}일) 2001 년 웨이 다시.

스크립틀릿 의 주요 단점 은 다음과 같습니다.

  1. 재사용 성 : 스크립틀릿을 재사용 할 수 없습니다.
  2. 교체 성 : 스크립틀릿을 추상적으로 만들 수 없습니다.
  3. OO 기능 : 상속 / 구성을 사용할 수 없습니다.
  4. 디버깅 가능성 : 스크립틀릿에서 예외가 절반 만 발생하면 빈 페이지 만 있으면됩니다.
  5. 테스트 가능성 : 스크립틀릿은 단위 테스트가 불가능합니다.
  6. 유지 보수성 : 혼합 / 정렬 / 복제 된 코드 로직을 유지 보수하려면 Saldo 당 더 많은 시간이 필요합니다.

또한 Sun Oracle 자체는 (태그) 클래스에서 동일한 기능이 가능할 때마다 스크립틀릿을 사용하지 않도록 JSP 코딩 규칙 에서 권장합니다 . 여기 몇 가지 관련성이 있습니다.

JSP 1.2 스펙에서 웹 애플리케이션에 JSP 표준 태그 라이브러리 (JSTL)를 사용 하여 페이지 에 JSP 스크립틀릿의 필요성을 줄이는 것이 좋습니다 . JSTL을 사용하는 페이지는 일반적으로 읽고 관리하기가 더 쉽습니다.

...

가능하면 태그 라이브러리가 동등한 기능을 제공 할 때마다 JSP 스크립틀릿을 사용하지 마십시오 . 이렇게하면 페이지를보다 쉽게 ​​읽고 유지 관리 할 수 ​​있으며 비즈니스 로직과 프리젠 테이션 로직을 분리 할 수 ​​있으며 페이지를 JSP 2.0 스타일 페이지로 쉽게 발전시킬 수 있습니다 (JSP 2.0 사양은 스크립틀릿 사용을 지원하지만 강조하지 않습니다).

...

비즈니스 로직에서 프리젠 테이션 티어 간의 결합을 줄이기 위해 MVC (Model-View-Controller) 디자인 패턴을 채택 한다는 개념 에서 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);
        }
    }

    또는 JSF , Spring MVC , Wicket 과 같은 MVC 프레임 워크를 채택하면 사용자 정의 서블릿이 필요하지 않고 JSP / Facelets 페이지와 JavaBean 클래스로 끝납니다.


  • JSP 페이지 내부 의 흐름제어 하기 위해 일부 Java 코드를 호출 하려면 JSTL core 와 같은 (기존) 흐름 제어 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.xml.

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

    Java EE에 포함 된 MVC 프레임 워크 JSF의 일부인 JSP의 후속 버전 인 Facelets 에서는 이미 스크립틀릿 을 사용할 수 없습니다 . 이 방법으로 자동으로 "올바른 방법"을 수행해야합니다.


  • JSP 페이지에서 "백엔드"데이터 에 액세스하고 표시 하기 위해 일부 Java 코드를 호출 하려면 EL (Expression Language)을 사용해야 ${}합니다. 예 : 제출 된 입력 값을 다시 표시 :

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

    ${param.foo}결과가 표시됩니다 request.getParameter("foo").


  • JSP 페이지에서 일부 유틸리티 Java 코드를 직접 호출 하려면 (일반적으로 public static메소드)이를 EL 함수로 정의해야합니다. JSTL 에는 표준 함수 taglib 가 있지만 직접 함수를 직접 작성할 수도 있습니다 . 다음 fn:escapeXmlXSS 공격 을 방지하기 위해 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 /와는 전혀 관련이 없으며, 개발하는 모든 웹 응용 프로그램 에서이 문제를 고려해야합니다 . 스크립틀릿 의 문제점은 최소한 표준 Java API를 사용하지 않는 내장 된 예방 방법을 제공하지 않는다는 것입니다. JSP의 후속 Facelets는 이미 암시적인 HTML 이스케이프 처리를 수행하므로 Facelets의 XSS 구멍에 대해 걱정할 필요가 없습니다.

또한보십시오:


117
+1 좋은 답변입니다. 그러나 언젠가는 스크립틀릿을 사용하는 것이 독단적이지만, 규칙을 입증하는 예외는 아닙니다.
svachon

26
@svachon : 스크립틀릿은 빠른 프로토 타이핑 / 테스트에 유용합니다. 지금까지 내가 아는 한, 즉 스크립틀릿의 하나 "합법적 인"제품 사용, 거기에 <% response.getWriter().flush(); %>사이 </head><body>에서는 WebBrowser에서 웹 페이지를 구문 분석 성능을 향상시키기는. 그러나 서버 측의 출력 버퍼 크기가 낮 으면 (1 ~ 2KB)이 사용은 무시해도됩니다. 이 기사도 참조하십시오 .
BalusC

5
@BalusC 몇 번이나 getter / setter 패턴을 따르지 않는 Java 클래스가 붙어 있습니다. IMHO는 scripltet이 작업을 수행하는 경우입니다.
svachon

41
@ svachon : 해당 클래스를 자체 Javabean 클래스로 감싸고 대신 사용합니다.
BalusC

31
꽤 좋은 대답이되었지만 doGet 및 doPost 부분이 잘못되었습니다. 이러한 메소드는 특정 요청 (HEAD, GET 및 POST) 메소드를 처리하기위한 것이며 "전처리"또는 "후 처리"요청에는 적합하지 않습니다!
MetroidFan2002

225

보호 수단으로 : 스크립틀릿을 사용하지 않도록 설정

으로 또 다른 문제는 논의, 당신은 항상 당신의 스크립틀릿을 사용하지 않도록해야 할 web.xml웹 응용 프로그램 설명자.

나는 개발자가 스크립틀릿을 추가하는 것을 방지하기 위해, 특히 조만간 개요를 잃을 수있는 대기업에서 항상 그렇게 할 것입니다. 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 주석보다는 이러한 주석을 사용하는 것이 유용하다는 것을 알았습니다.
David Lavender

16
@MrSpoon이 답변을 추적했습니다. 이 답변 + 설명에 따라 스크립틀릿 <% %>, 스크립틀릿 표현식 <%! %>및 스크립틀릿 선언 이 해제됩니다 <%= %>. 즉, 지시문 <%@ %>과 주석은 <%-- --%>계속 활성화되어 있고 사용 가능하므로 여전히 주석과 포함을 수행 할 수 있습니다.
마틴 카니

3
스크립틀릿 지시문을 사용하지 않도록 설정하는 것은 끔찍할 것입니다. 공백을 다듬는 레거시 시스템과 상호 작용하는 데 공백 공백은 매우 중요합니다.
corsiKa

108

JSTL 은 조건부, 루프, 집합, 가져 오기 등에 대한 태그를 제공합니다. 예를 들면 다음과 같습니다.

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

JSTL은 요청 속성과 함께 작동합니다 . JSP로 전달 되는 서블릿에 의해 요청에서 가장 자주 설정됩니다 .


2
왜 JSTL이 요청 속성과 함께 작동한다고 말합니까? 그들은 어떤 범위에서든 속성으로 작업 할 수 있습니까?
Koray Tugay

60

이것이 올바른지 확실하지 않습니다.

MVC에 대해 읽어야합니다. Spring MVC & Struts 2 는 가장 일반적인 두 가지 솔루션입니다.


29
MVC는 Spring 또는 Struts없이 위의 많은 기술을 사용하여 서블릿 / jsp로 구현할 수 있습니다.
stepanian 2019

18
질문에 어떻게 대답합니까?
xyz

54

Java와 HTML 코드의 혼합을 피하기 위해 EL 표현식과 함께 JSTL 태그를 사용할 수 있습니다.

<%@ 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

Wicket 과 같은 구성 요소 기반 프레임 워크도 있으므로 많은 HTML을 생성 할 수 있습니다. HTML로 끝나는 태그는 매우 기본적이고 거의 섞이지 않는 논리가 없습니다. 결과는 일반적인 HTML 요소가있는 거의 빈 HTML 페이지입니다. 단점은 Wicket API에 배울 구성 요소가 많으며 이러한 제약 조건에서 달성하기 어려운 것이 있다는 것입니다.


33

MVC 아키텍처 패턴에서 JSP는보기 계층을 나타냅니다. JSP에 Java 코드를 포함시키는 것은 나쁜 습관으로 간주됩니다. JSP와 함께 JSTL , freeMarker , velocity 를 "template engine"으로 사용할 수 있습니다 . 해당 태그 에 대한 데이터 공급자 는 처리 중인 프레임 워크에 따라 다릅니다 . Struts 2webworkMVC 패턴의 구현으로 사용 OGNL "JSP로 콩의 속성을 노출하는 것은 매우 흥미있는 기술".


27

경험에 따르면 JSP에는 몇 가지 단점이 있으며 그중 하나는 실제 코드와 마크 업을 혼합하는 것을 피하기 어렵습니다.

가능하다면 전문 기술을 사용하여 필요한 작업을 고려하십시오. Java EE 6에는 JSF 2.0이 있으며,이 #{bean.method(argument)}방법을 통해 Java Bean을 JSF 페이지와 함께 붙이는 등 많은 유용한 기능을 제공합니다 .


3
오래된 대답이지만 JSF가 Java 공간에서 가장 끔찍한 발명품 중 하나라고 말할 수는 없습니다. 단일 (HTTP GET과 같은) 링크를 만들면 이유를 이해할 수 있습니다.
Alex

@Alex이지만 여전히 더 좋습니다. 더 좋은 것을 추천 해주세요.
Thorbjørn Ravn Andersen

26

JSP에서 Java 코딩의 단점을 피하고 싶다면 scriplet으로도 그렇게 할 수 있습니다. 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은 EviL입니다 (런타임 예외, 리팩토링)
Wicket도 악의적 일 수 있습니다 (성능, 작은 앱이나 간단한 뷰 티어

에는 어려움 ). java2s의 예제 ,

웹 애플리케이션의 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

25

Wicket은 또한 Java를 HTML과 완전히 분리하는 대안이므로 디자이너와 프로그래머는 서로를 거의 이해하지 않고도 서로 다른 코드 세트에서 함께 작업 할 수 있습니다.

Wicket을보십시오.


23

좋은 질문을 제기했지만 좋은 답변을 얻었지만 JSP를 제거하는 것이 좋습니다. 구식 기술은 결국 죽을 것입니다. 템플릿 엔진과 같은 현대적인 접근 방식을 사용하십시오. 비즈니스 계층과 프리젠 테이션 계층을 명확하게 분리하고 템플릿에 Java 코드가 없으므로 WYSIWYG를 사용하는 대부분의 경우 웹 프리젠 테이션 편집 소프트웨어에서 직접 템플릿을 생성 할 수 있습니다.

그리고 필터와 사전 및 사후 처리를 피하십시오. 그렇지 않으면 변수가 값을 얻는 위치를 항상 알지 못하므로 지원 / 디버깅 문제를 해결할 수 있습니다.


9
JSP 자체는 템플릿 엔진입니다
WarFox

1
-1- 필터, 전 처리기 및 후 처리기를 사용해야하는 완전히 유효한 이유 가 많이 있습니다 . 그렇습니다. 신비한 것처럼 보이는 값으로 끝날 수 있지만 아키텍처를 이해하면 아닙니다.
RustyTheBoyRobot 2016 년

21

JSP 파일에서 자바 코드를 피하기 위해 자바는 이제 JSTL과 같은 태그 라이브러리를 제공합니다. 또한 자바는 태그 형태로 모든 프로그래밍 구조를 작성할 수있는 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>

이 mater 페이지에서 "title"이라는 조각을 작성하여 하위 페이지에서이 마스터 페이지의이 위치에 더 많은 코드를 삽입 할 수 있습니다. 또한 태그 <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 파일을 쉽게 호출 할 수 있습니다. 이것은 또한 스트럿 프레임 워크와 잘 작동합니다


"어떻게 피하려고하더라도 다른 개발자와 작업 할 때 일부 개발자는 여전히 스크립틀릿을 선호하고 프로젝트에 악의적 인 코드를 삽입합니다." "Safeguard로 : 스크립틀릿 사용 안 함"답변을 참조하십시오.
Lluis Martinez



17

누군가가 둘 이상의 언어로 프로그래밍하는 것에 실제로 반대하는 경우 GWT를 제안합니다. 이론적으로 모든 툴킷 및 HTML 요소를 피할 수 있습니다 .Google 툴킷은 모든 클라이언트 및 공유 코드를 JS로 변환하기 때문에 문제가 없으므로 다른 언어로 코딩하지 않고 웹 서비스가 있습니다. 확장 (smartGWT 또는 Vaadin)으로 제공되는 곳에서 기본 CSS를 사용할 수도 있습니다. 수십 개의 주석을 배울 필요가 없습니다.

물론 원하는 경우 코드의 깊이에 빠져 JS를 삽입하고 HTML 페이지를 풍부하게 할 수 있지만 실제로 원하는 경우 피할 수 있으며 다른 프레임 워크에서 작성된 것처럼 결과가 좋습니다. 시도해 볼만한 가치가 있으며 기본 GWT는 잘 문서화되어 있습니다.

그리고 물론 많은 동료 프로그래머들이 몇 가지 다른 솔루션을 설명하거나 추천했습니다. GWT는 웹 파트를 다루거나 최소화하고 싶지 않은 사람들을위한 것입니다.


1
실제로 OP의 질문에 대답하지 않습니다.
Evan Donovan

1
@EvanDonovan 글쎄, 실제로 대답을합니다. 다른 언어와 섞이는 Java 코드를 망칠 필요가 없습니다. 코딩에 Java를 사용한다고 인정하지만 Java 호출없이 JS로 변환됩니다. 그러나 질문의 ​​범위는 고전적인 JSP의 혼란을 피하는 방법입니다. 그리고 GWT 기술이이를 해결합니다. 아무도 언급하지 않았기 때문에이 답변을 추가했지만 JSP의 대안이므로 관련이 있습니다. 나는 질문의 전체 범위에 대답하고 싶지 않지만 대안을 찾고있는 사람들을 위해 귀중한 정보를 추가하고 싶었습니다.
CsBalazsHungary

16

파이썬 세계의 깔끔한 아이디어는 템플릿 속성 언어입니다 . TAL은 Zope (따라서 "Zope Page Templates", 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

나는 Facelets를 잘 모르지만 IIRC는 사용자 정의 XML 요소를 구현하는 클래스를 작성하는 것입니다. TAL / ZPT 방식은 원본 요소를 채우거나 대체하는 특수 속성이있는 참 (X) HTML을 포함하는 템플릿을 갖는 것입니다. 따라서 작업 템플릿을보고 멋진 더미 컨텐츠가 포함 된 프로토 타입을 볼 수 있습니다. Facelets가 사용자 정의 속성을 사용하여 원래 HTML 요소 (추가 네임 스페이스 없음)를 조정할 수 있는지 확실하지 않습니다.
Tobias

방금이 Facelets 물건을 다시 보았습니다. 여기에는 모든 종류의 검증 기능 등이 포함되어 있으므로 TAL과 완전히 다른 철학을 따릅니다. TAL 방식은 "템플릿에서 로직을 최대한 깨끗하게 유지하십시오. 복잡한 모든 작업은 컨트롤러에 의해 수행되어야합니다." 디자이너에게 Facelets 템플릿을 제공하여 수정하지 않아도됩니다. 불가능합니다. 생성 된 컨텐츠와 관련하여 tal:replace="structure (expression)"항상 속성을 사용하는 것과 같습니다 .
Tobias


14

물론 교체 <%! counter++; %>비즈니스 계층에 카운터를 늘릴 필요성에 대해 알리고 이벤트에 따라 반응하고 발표자에게 뷰를 업데이트하도록 알리는 이벤트 생산자-소비자 아키텍처로 . 미래에는 카운터의 새로운 가치와 오래된 가치, 누가 그것을 증가 시켰으며 어떤 목적을 염두에 두어야하는지에 따라 많은 데이터베이스 트랜잭션이 수반됩니다. 레이어가 완전히 분리되어 있으므로 직렬화가 필요합니다. RMI, IIOP, SOAP보다 카운터를 증가시킬 수 있습니다. 그러나 HTML은 필수입니다. 구현하지 않는 것은 일반적인 경우이므로 구현하지 않습니다. 새로운 목표는 새로운 반짝이는 E7, 64GB RAM 서버에서 초당 250 씩 증가하는 것입니다.

저는 프로그래밍 분야에서 20 년이 넘는 시간을 보냈는데 대부분의 프로젝트는 섹스텟 이전에 실패했습니다. 재사용 성 대체 가능성 OO- 능력 디버깅 가능성 테스트 가능성 유지 관리도 필요합니다. 기능에만 관심이있는 사람들이 운영하는 다른 프로젝트는 매우 성공적이었습니다. 또한 프로젝트에서 너무 일찍 구현 된 견고한 객체 구조로 인해 사양의 급격한 변화 (일명 민첩)에 코드를 적용 할 수 없습니다.

따라서 프로젝트 초기에 또는 특별히 필요하지 않은 경우 "레이어"또는 중복 데이터 구조를 정의하는 활동을 지연으로 간주합니다.  


11

기술적으로 JSP는 런타임 동안 모두 서블릿으로 변환됩니다 . JSP는 처음에 MVC 패턴에 따라 비즈니스 로직과 디자인 로직을 분리하기 위해 만들어졌습니다. 따라서 JSP는 런타임 동안 기술적으로 모든 Java 코드입니다. 그러나 질문에 대답하기 위해 태그 라이브러리는 일반적으로 JSP 페이지에 논리 (Java 코드 제거)를 적용하는 데 사용됩니다.


8

Java 웹 애플리케이션에서 다음을 사용하면 JSP의 전경에서 Java 코드를 제거 할 수 있습니다.

  1. 웹 애플리케이션에 MVC 아키텍처 사용

  2. JSP 태그 사용

    ㅏ. 표준 태그

    비. 맞춤 태그

  3. 표현 언어


8

JSP 파일에서 Java 코드를 피하는 방법은 무엇입니까?

Expression Language ( EL ) 외에 JSTL 과 같은 탭 라이브러리 태그를 사용할 수 있습니다 . 그러나 EL은 JSP에서 잘 작동하지 않습니다. 따라서 JSP를 완전히 삭제하고 Facelets를 사용하는 것이 좋습니다 .

FaceletsJSF (Java Server Faces) 를 위해 설계된 최초의 비 JSP 페이지 선언 언어 로 JSP와 비교하여 JSF 개발자에게보다 단순하고 강력한 프로그래밍 모델을 제공했습니다. 웹 애플리케이션 개발을 위해 JSP에서 발생하는 다양한 문제를 해결합니다.

여기에 이미지 설명을 입력하십시오

출처


나는 분명히이 반응을 두 번째로한다. Facelets가 있거나없는 JSF. JSP에서 개발하는 것이 10 년 전에 크게 중단되었다고 생각했습니다. 2000 년에 JSP를 마지막으로 썼습니다!
casgage

4

스크립틀릿을 사용하는 것은 매우 오래된 방법이므로 권장하지 않습니다. JSP 페이지에서 직접 출력하려면 JSTL 과 함께 Expression Language (EL) 를 사용하십시오 .

Velocity, Freemarker, Thymeleaf 등과 같은 템플릿 엔진을 사용하는 것과 같은 다른 옵션도 있습니다. 그러나 EL 및 JSTL과 함께 일반 JSP를 사용하면 대부분의 목적을 달성 할 수 있으며 초보자에게는 가장 간단한 것으로 보입니다.

또한 뷰 계층에서 비즈니스 로직을 수행하는 것이 가장 좋은 방법은 아니며 서비스 계층에서 비즈니스 로직을 수행하고 출력 결과를 Controller를 통해 뷰에 전달해야합니다.


3

그 어느 것도 더 이상 내 친구에게 사용되지 않으며, 조언은 서버에서보기 (css, html, javascript 등)를 분리하는 것입니다.

필자의 경우 Angular로 뷰를 처리하는 시스템을 수행하고 필요한 데이터는 나머지 서비스를 사용하여 서버에서 가져옵니다.

날 믿어, 이것이 당신의 디자인 방식을 바꿀 것입니다


3

UI 디자인을 위해 자바 스크립트 프레임 워크와 같은 각도를 가진 backbone을 사용하고 나머지 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, 액세스 session, request... 태그 파일에 너무.

태그 파일 은 JSP 파일과 같이 변경시 서버를 다시 시작할 필요가 없으므로 매우 쉽게 개발할 수 있습니다. 이를 통해 개발이 쉬워집니다.

좋은 태그가 많은 Struts 2와 같은 프레임 워크를 사용하더라도 고유 한 태그를 사용하면 코드를 많이 줄일 수 있습니다. 태그 매개 변수를 스트럿에 전달하면 프레임 워크 태그를 사용자 정의 할 수 있습니다.

태그를 사용하여 Java를 피할뿐만 아니라 HTML 코드를 최소화 할 수도 있습니다. 내 페이지에서 코드 중복이 시작되는 즉시 HTML 코드를 검토하고 태그를 많이 작성하려고합니다.

(당신이 JSP 코드에서 java를 사용하더라도 결국 태그를 사용하여 해당 코드를 캡슐화 할 수 있습니다)


1

많은 답변에서 알 수 있듯이 JSTL을 사용하거나 사용자 정의 태그를 작성하십시오. 다음 은 맞춤 태그 생성에 대한 좋은 설명입니다.


1
  1. 서블릿 클래스 내에서 값과 매개 변수 만들기
  2. JSTL / Taglib을 사용하여 JSP 내에서 해당 값과 매개 변수를 가져옵니다.

이 방법의 좋은 점은 코드가 HTML과 같은 코드라는 것입니다!


0

EL 표현식과 함께 JSTL 태그를 사용하면이를 피할 수 있습니다. 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.