ProgramingTip

JSP / 서블릿의 숨겨진 기능

bestdevel 2020. 10. 16. 07:45
반응형

JSP / 서블릿의 숨겨진 기능


JSP / Servlet을 사용할 때 사용되는 트릭 관심이 있습니다. 시작하겠습니다 :

최근에 한 JSP 태그의 출력을 다른 태그의 속성에 포함하는 방법을 알아 듣습니다.

<c:forEach items="${items}">
  <jsp:attribute name="var">
    <mytag:doesSomething/>
  </jsp:attribute>
  <jsp:body>
    <%-- when using jsp:attribute the body must be in this tag --%>
  </jsp:body>
</c:forEach>

참고 : JSP / Servlet에 대한 "숨겨진 기능"을 생각하기가 어렵습니다. 제 생각에는 "모범 사례"가 더 나은 표현이며 그 중 하나를 생각할 수 있습니다. 또한 JSP / Servlet에 대한 경험에 따라 달라집니다. 수년간 개발 한 후에는 더 이상 "숨겨진 기능"을 볼 수 없습니다. 어쨌든, 나는 많은 선발자들이 완전히 인식하지 않는다는 것을 몇 년 동안 내가 발견 한 작은 "모범 사례"중 일부를 할 것입니다. 많은 선발자들의 눈에 전도은 "숨겨진 기능"분류로 될 것입니다. 어쨌든, 여기에 목록이 있습니다 :)


직접 액세스에서 JSP 페이지 배포

JSP 파일을 /WEB-INF폴더에 배치 하면 예를 들어 직접 액세스 할 수있는 복잡한 숨길 수 있습니다 http://example.com/contextname/WEB-INF/page.jsp. 결과적으로 404. 그런 다음 Servlet 또는을 사용하여 액세스 할 수 있습니다 .RequestDispatcherjsp:include


JSP에 대한 전처리 요청

대부분은 요청 (양식 신청) 사후 처리하는 서블릿에 대해 대부분의 서블릿 사용 하여 JSP에 대한 요청 사전 처리 할 수 있습니다. 예를 들면 :doPost()doGet()

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    List<Item> items = itemDAO.list();
    request.setAttribute("items", items);
    request.getRequestDispatcher("/WEB-INF/page.jsp").forward(request, response);
}

JSTL의 도움으로 표시되는 일부 테이블 형식 데이터를 미리로드하는 데 사용 c:forEach됩니다.

<table>
    <c:forEach items="${items}" var="item">
        <tr><td>${item.id}</td><td>${item.name}</td></tr>
    </c:forEach>
</table>

이러한 서블릿을 url-pattern/page(또는 /page/*) 에 매핑 http://example.com/contextname/page하고 브라우저 주소-display 줄이나 또는 일반 바닐라-link로 호출 하여 실행합니다. 예를 들어 서블릿의 doGet 및 doPost 도 참조하십시오 .


동적 포함

다음에서 EL을 사용할 수 있습니다 .jsp:include

<jsp:include page="/WEB-INF/${bean.page}.jsp" />

bean.getPage()단지 유효한 페이지 이름을 반환 할 수 있습니다.


EL은 모든 게터에 액세스 할 수 있습니다.

EL은 그 자체로 할 수있는 완전한 Javabean 이 접근 요구하지 않습니다 . 접두사 get또는 isEL에서 액세스 충분한 인수가없는 메소드의 존재 . 예 :

${bean['class'].name}

이 방법이 상속 된 위치 의 값을 반환합니다 . 참조 "중괄호 표기법"을 사용하여 지정합니다 여기에 표현 된 인스턴스의 인스턴스 확인 .bean.getClass().getName()getClass()Object#getClass()class[]

${pageContext.session.id}

ao에서 유용한 값을 리턴합니다 . 애플릿이 서블릿의 인스턴스와 통신 할 수 있습니까 ?pageContext.getSession().getId()

${pageContext.request.contextPath}

ao에서 유용한 값을 반환합니다 . 서버 루트 이름을 포함하지 않고 상대 경로를 사용하는 방법은 무엇입니까?pageContext.getRequest().getContextPath()


EL 은지도에도 액세스 할 수 있습니다.

다음 EL 표기법

${bean.map.foo}

로 확인 bean.getMap().get("foo")됩니다. Map에 점이 포함 키 된 경우 []따옴표로 묶인 키와 함께 "중괄호 표기법" 사용할 수 있습니다 .

${bean.map['foo.bar']}

해결 bean.getMap().get("foo.bar")됩니다. 동적 키를 원하면 중괄호 표기법도 사용하고 따옴표를 사용하지 않습니다.

${bean.map[otherbean.key]}

해결 bean.getMap().get(otherbean.getKey())됩니다.


JSTL로 맵 반복

을 ( 를) 반복하는 데에도 사용할 수 있습니다 . 반복은 각 차례로 메소드 를 갖는 제공 합니다 (따라서 EL에서 와로 액세스 할 수 있습니다 ). 예 :c:forEachMapMap.EntrygetKey()getValue()${entry.key}${entry.value}

<c:forEach items="${bean.map}" var="entry">
    Key: ${entry.key}, Value: ${entry.value} <br>
</c:forEach>

예를 들어 jstl로 주문을 참조하십시오 -정확히 어떻게?


JSP에서 현재 날짜 가져 오기

jsp:useBeanJSTL을 사용 하여 현재 날짜를 날짜 형식을 이용할 수 있습니다.fmt:formatDate

<jsp:useBean id="date" class="java.util.Date" />
...
<p>Copyright &copy; <fmt:formatDate value="${date}" pattern="yyyy" /></p>

다음과 같이 인쇄됩니다 (현재) : "Copyright © 2010".


쉬운 접근 한 URL

쉬운 URL을 사용하는 쉬운 방법 다음 에서 숨겨진 JSP를 사용하는 것 입니다 .HttpServletRequest#getPathInfo()/WEB-INF

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    request.getRequestDispatcher("/WEB-INF" + request.getPathInfo() + ".jsp").forward(request, response);
}

예를 들어이 서블릿을 매핑하면 대한 /pages/*요청 http://example.com/contextname/pages/foo/bar이 서열 표시 /WEB-INF/foo/bar.jsp됩니다. 경로 정보를 분할하여 한 단계 더 나아갈 /있고 첫 번째 부분은 JSP 페이지 URL로, 나머지 부분은 "비즈니스 작업"으로 사용됩니다 (서블릿이 페이지 컨트롤러 역할을 ). 예를 들어 디자인 패턴 웹 기반 응용 프로그램을 참조하십시오 .


다음을 사용하여 사용자 입력 다시 표시 ${param}

암시 EL 의미 ${param}표현 형태가 JSP로 전송 한 후 사용자의 입력을 다시 표시하기 위해 수있다 :HttpServletRequest#getParameterMap()

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

이것은 기본적으로 request.getParameterMap().get("foo"). 예를 들어 서블릿에 양식을 제출 한 후 JSP에서 HTML 양식 필드 값을 어떻게 유지할 수 있습니까?
XSS를 방지하는 것을 잊지 마세요! 다음 장을 참조하십시오.


XSS를 방지하는 JSTL

XSS 에서 사이트를 방지하려면 JSTL 또는 .NET을 사용하여 사용자 제어 데이터 를 (재) 표시 하기 만하면 됩니다.fn:escapeXmlc:out

<p><input type="text" name="foo" value="${fn:escapeXml(param.foo)}">
<p><c:out value="${bean.userdata}" />

<table>행을 번갈아 가며LoopTagStatus

varStatusJSTL 속성 은 여러 getter 메소드 (EL에서 사용할 수 있음)가 c:forEach있는 LoopTagStatus백을 제공합니다 . 따라서 짝수 행을 확인하려면 loop.getIndex() % 2 == 0다음 사항을 확인하십시오 .

<table>
    <c:forEach items="${items}" var="item" varStatus="loop">
        <tr class="${loop.index % 2 == 0 ? 'even' : 'odd'}">...</tr>
    <c:forEach>
</table>

효과적으로 끝날 것입니다

<table>
    <tr class="even">...</tr>
    <tr class="odd">...</tr>
    <tr class="even">...</tr>
    <tr class="odd">...</tr>
    ...
</table>

CSS를 사용하여 다른 배경색을 지정하십시오.

tr.even { background: #eee; }
tr.odd { background: #ddd; }

목록 / 배열에서 쉼표로 구분 된 문자열을 다음으로 채 웁니다 LoopTagStatus.

또 다른 유용한 LoopTagStatus방법은 다음과 isLast()같습니다.

<c:forEach items="${items}" var="item" varStatus="loop">
    ${item}${!loop.last ? ', ' : ''}
<c:forEach>

결과는 item1, item2, item3.


EL 기능

public static유틸리티 메소드를 EL 함수 (예 : JSTL 함수 ) 선언 하여 EL에서 사용할 수 있습니다.

package com.example;

public final class Functions {
     private Functions() {}

     public static boolean matches(String string, String pattern) {
         return string.matches(pattern);
     }
}

함께 /WEB-INF/functions.tld하는 다음과 같이 :

<?xml version="1.0" encoding="UTF-8" ?>
<taglib 
    xmlns="http://java.sun.com/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
    version="2.1">

    <tlib-version>1.0</tlib-version>
    <short-name>Custom_Functions</short-name>
    <uri>http://example.com/functions</uri>

    <function>
        <name>matches</name>
        <function-class>com.example.Functions</function-class>
        <function-signature>boolean matches(java.lang.String, java.lang.String)</function-signature>
    </function>
</taglib>

다음과 같이 사용할 수 있습니다.

<%@taglib uri="http://example.com/functions" prefix="f" %>

<c:if test="${f:matches(bean.value, '^foo.*')}">
    ...
</c:if>

원래 요청 URL 및 쿼리 문자열 가져 오기

JSP가 전달 된 경우 다음을 통해 원래 요청 URL을 가져올 수 있습니다.

${requestScope['javax.servlet.forward.request_uri']} 

원래 요청 쿼리 문자열은 다음과 같습니다.

${requestScope['javax.servlet.forward.query_string']}

그게 다였습니다. 조만간 더 추가 할 수 있습니다.

참고 URL : https://stackoverflow.com/questions/2523430/hidden-features-of-jsp-servlet

반응형