簡體   English   中英

這是使用JSP scriptlet的可接受的案例嗎?

[英]Is this an acceptable case to use a JSP scriptlet?

我知道使用JSP scriptlet通常是不受歡迎的,這就是為什么我想知道是否有一種更優雅的方式來實現我想要做的事情。 我正在創建一個視圖,並且根據域模型中的某些情況,我正在呈現不同的HTML。

例如,考慮用戶可能處於角色中的場景。 這樣的方法在User模型類中定義:

public boolean isInRole(String roleName) {
    // Logic here to determine if the user is in a role
}

然后我們有一個JSP,如下所示:

<%
    User user = (User)request.getAttribute("user");
%>

// Some HTML here...

<% if (user.isInRole("admin") { %>
    // Generate some admin menu here
<% } %>

據我所知,使用JSTL / EL無法做到這一點。 在這里使用scriptlet聽起來是個好主意嗎? 或者我應該采取另一種方法嗎?

謝謝你的任何建議。

我要么升級到Servlet 3.0 / JSP 2.2,要么在EL中調用帶參數的方法

<c:if test="${user.isInRole('admin')}">

或創建自定義EL功能

<c:if test="${util:isUserInRole(user, 'admin')}">

根據您的問題歷史,您似乎已經在使用JEE6。 所以第一種方法應該適合你(如果你的web.xml聲明符合Servlet 3.0規范)。

您還可以創建自定義標記來完成此操作。 這是一個簡單的例子:

創建一個新的tld文件:WEB-INF / user.tld

<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag 
Library 1.2//EN"
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name></short-name>
    <tag>
       <name>user</name>
       <tag-class>tags.UserRoleTag</tag-class>
       <body-content>JSP</body-content>
       <attribute>
          <name>roles</name>
          <required>true</required>
          <rtexprvalue>true</rtexprvalue>
       </attribute>
    </tag>
</taglib>

創建自定義標記類:tags / UserRoleTag.java

package tags;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;

@SuppressWarnings("serial")
public class UserRoleTag extends TagSupport {
  private String roles;

  public int doStartTag() throws JspException {
    String userRole = (String)pageContext.getAttribute("currentUserRole");

    return roles.contains(userRole) ? EVAL_BODY_AGAIN : SKIP_BODY;
  }

  public String getRoles() {
    return roles;
  }

  public void setRoles(String roles) {
    this.roles = roles;
  }
}

創建你的jsp:warfolder / home.jsp

<%@ taglib uri="/WEB-INF/user.tld" prefix="u" %>

<% pageContext.setAttribute("currentUserRole", "admin"); // this value would come from the controller... %>

<u:user roles="admin registered">
    welcome admin!
</u:user>

<u:user roles="guest">
    welcome guest!
</u:user>

采用這種方法可以使您的模型和標簽保持松散耦合,並且最有可能在其他項目中重復使用。

我使用的經驗法則是scriptlets(或JSP標簽或EL)必須只使用已經由控制器設置的模型,而不是觸發與后端系統交互並獲取內容的操作。

差異往往是微妙的,但在我看來是非常重要的。 在您的示例中,我們假設確定用戶是否處於管理員角色需要您訪問某個數據庫或進行Web服務調用。 然后,您將通過從視圖中觸發該操作來違反MVC。 無論是從scriptlet調用操作還是從JSP標記調用EL都是無關緊要的。 你做過最好由控制器完成的事情。

那么我該如何解決這個問題呢? 我會把確定用戶是否處於管理員角色的邏輯放入控制器。 然后,我將在模型中提供此信息,以便視圖可以使用該模型來確定用戶是否處於管理員角色。 然后,簡單的$ {user.isAdmin}將從視圖中回答問題。 該觀點不會被“指責”觸發任何行動。

那么,作為這種禁令的堅持者,我是純粹主義者嗎? 我發現在需要優化應用程序的許多情況下,我更容易掃描控制器並優化他們正在做的事情。 如果視圖還觸發后端工作,那么進行這種優化將非常困難,因為后端交互將分散在多個控制器和視圖中。

這也違反了單一責任原則。 希望這能回答你的問題。

順便說一句,很棒的問題。 我很高興您正在考慮這個細節。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM