gpt4 book ai didi

jsp - JSP/Servlet 的隐藏特性

转载 作者:行者123 更新时间:2023-12-03 05:18:10 25 4
gpt4 key购买 nike

关闭。这个问题需要更多focused .它目前不接受答案。












想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post .

5年前关闭。




Improve this question




我对您在编写 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 的经验。经过多年的发展,您再也看不到那些“隐藏的功能”了。无论如何,我将列出一些我多年来发现许多初学者并没有完全意识到的小“最佳实践”。在许多初学者的眼中,这些将被归类为“隐藏功能”。无论如何,这是 list :)

隐藏 JSP 页面以防止直接访问
通过在 /WEB-INF 中放置 JSP 文件您可以通过例如 http://example.com/contextname/WEB-INF/page.jsp 有效地将它们隐藏起来,使其无法直接访问。 .这将导致 404 .然后,您只能通过 RequestDispatcher 访问它们。在 Servlet 中或使用 jsp:include .

JSP 的预处理请求
大多数人都知道 Servlet 的 doPost() 发帖 - 处理请求(表单提交),但大多数人不知道您可以使用 Servlet 的 doGet() 方法到 - 处理对 JSP 的请求。例如:

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 上映射这样的 servlet的 /page (或 /page/* )然后调用 http://example.com/contextname/page通过浏览器地址栏或一个普通的链接来运行它。另见例如 doGet and doPost in Servlets .

动态包含
您可以在 jsp:include 中使用 EL :
<jsp:include page="/WEB-INF/${bean.page}.jsp" />
bean.getPage()可以只返回一个有效的页面名称。

EL 可以访问任何 getter
EL 本身并不要求要访问的对象是完整的 Javabean。存在前缀为 get 的无参数方法或 is足以在 EL 中访问它。例如:
${bean['class'].name}
这将返回 bean.getClass().getName() 的值哪里 getClass()方法实际上继承自 Object#getClass() .请注意 class使用“大括号表示法”指定 []由于这里提到的原因 instanceof check in EL expression language .
${pageContext.session.id}
这将返回 pageContext.getSession().getId() 的值这在 a.o. 中很有用 Can an applet communicate with an instance of a servlet .
${pageContext.request.contextPath}
这将返回 pageContext.getRequest().getContextPath() 的值这在 a.o. 中很有用 How to use relative paths without including the context root name?

EL 也可以访问 map
以下 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 迭代 Map
您可以使用 c:forEach 以及迭代 Map .每次迭代都会给出 Map.Entry 依次是 getKey()getValue()方法(这样您就可以在 EL 中通过 ${entry.key}${entry.value} 访问它)。示例:
<c:forEach items="${bean.map}" var="entry">
Key: ${entry.key}, Value: ${entry.value} <br>
</c:forEach>
另见例如 Debugging with jstl - how exactly?

在 JSP 中获取当前日期
您可以使用 jsp:useBean 获取当前日期并在 JSTL 的帮助下对其进行格式化 fmt:formatDate
<jsp:useBean id="date" class="java.util.Date" />
...
<p>Copyright &copy; <fmt:formatDate value="${date}" pattern="yyyy" /></p>
这打印(截至目前)如下:“Copyright © 2010”。

简单友好的 URL
获得友好 URL 的一种简单方法是使用 HttpServletRequest#getPathInfo() 和 JSP 隐藏在 /WEB-INF 中:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF" + request.getPathInfo() + ".jsp").forward(request, response);
}
如果您将此 servlet 映射到例如 /pages/* ,然后在 http://example.com/contextname/pages/foo/bar 上发出请求将有效地显示 /WEB-INF/foo/bar.jsp .您可以通过拆分 / 上的路径信息来更进一步。并且只将第一部分作为 JSP 页面 URL,剩余部分作为“业务操作”(让 servlet 充当页面 Controller )。另见例如 Design Patterns web based applications .

使用 ${param} 重新显示用户输入
隐式 EL 对象 ${param}这是指 HttpServletRequest#getParameterMap() 可用于在 JSP 中提交表单后重新显示用户输入:
<input type="text" name="foo" value="${param.foo}">
这基本上与 request.getParameterMap().get("foo") 相同.另见例如 How can I retain HTML form field values in JSP after submitting form to Servlet?
不要忘记防止 XSS!请参阅以下章节。

JSTL 防止 XSS
防止您的网站被 XSS ,您需要做的就是(重新)显示 用户控制使用 JSTL 的数据 fn:escapeXml c:out .
<p><input type="text" name="foo" value="${fn:escapeXml(param.foo)}">
<p><c:out value="${bean.userdata}" />

交替 <table>LoopTagStatus 的行 varStatus JSTL 的属性 c:forEach 给你一个 LoopTagStatus back 又具有几个 getter 方法(可以在 EL 中使用!)。因此,要检查偶数行,只需检查是否 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 functions ),以便您可以在 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']}

到此为止。也许我迟早会添加更多。

关于jsp - JSP/Servlet 的隐藏特性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2523430/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com