code

EL에서 상수를 참조하는 방법은 무엇입니까?

codestyles 2020. 8. 16. 20:21
반응형

EL에서 상수를 참조하는 방법은 무엇입니까?


JSP 페이지에서 EL로 상수를 어떻게 참조합니까?

Addresses라는 상수 가있는 인터페이스 URL있습니다. 다음으로 이동하여 스크립트로 참조 할 수 있다는 것을 알고 <%=Addresses.URL%>있지만 EL을 사용하여 어떻게 수행합니까?


EL 3.0 이상

이미 Java EE 7 / EL 3.0 @page import을 사용중인 경우은 EL 범위의 클래스 상수도 가져옵니다.

<%@ page import="com.example.YourConstants" %>

이것은을 통해 가져 와서 ImportHandler#importClass()사용할 수 있습니다 ${YourConstants.FOO}.

모든 것을 참고 java.lang.*클래스가 이미 암시 적 수입과 같이 사용할 수 있습니다 ${Boolean.TRUE}${Integer.MAX_VALUE}. 초기 버전에 버그가 있었으므로 최신 Java EE 7 컨테이너 서버 만 필요합니다. 예 : GlassFish 4.0 및 Tomcat 8.0.0-1x는 실패하지만 GlassFish 4.1+ 및 Tomcat 8.0.2x +는 작동합니다. 그리고 web.xml서버에서 지원하는 최신 서블릿 버전을 준수하도록 선언 되었는지 확인해야 합니다. 따라서 web.xmlServlet 2.5 또는 이전 버전에 적합하다고 선언 된에서는 Servlet 3.0+ 기능이 작동하지 않습니다.

또한이 기능은 Facelet이 아닌 JSP에서만 사용할 수 있습니다. JSF + Facelets의 경우 가장 좋은 방법은 아래와<o:importConstants> 같이 OmniFaces사용 하는 것입니다.

<o:importConstants type="com.example.YourConstants" />

또는 ImportHandler#importClass()아래와 같이 호출하는 EL 컨텍스트 리스너를 추가 합니다.

@ManagedBean(eager=true)
@ApplicationScoped
public class Config {

    @PostConstruct
    public void init() {
        FacesContext.getCurrentInstance().getApplication().addELContextListener(new ELContextListener() {
            @Override
            public void contextCreated(ELContextEvent event) {
                event.getELContext().getImportHandler().importClass("com.example.YourConstants");
            }
        });
    }

}

EL 2.2 이상

입니다 하지 EL 2.2 이상에서 가능합니다. 몇 가지 대안이 있습니다.

  1. Map<String, Object>응용 프로그램 범위에 넣으십시오 . EL에서지도 값으로 보통 자바 빈즈의 방법으로 액세스 할 수 있습니다 ${map.key}또는 ${map['key.with.dots']}.

  2. 사용 <un:useConstants>이 Unstandard 태그 라이브러리 (maven2는 REPO 여기 )

    <%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %>
    <un:useConstants className="com.example.YourConstants" var="constants" />
    

    이렇게하면 .NET에서 일반적인 Javabean 방식으로 액세스 할 수 있습니다 ${constants.FOO}.

  3. 이 기사 하단에 설명 된 대로 Javaranch의 CCC <ccc:constantsMap>사용 하십시오 .

    <%@ taglib uri="http://bibeault.org/tld/ccc" prefix="ccc" %>
    <ccc:constantsMap className="com.example.YourConstants" var="constants" />
    

    이렇게하면 일반적인 Javabean 방식으로 ${constants.FOO}액세스 할 수 있습니다.

  4. JSF2를 사용 <o:importConstants>하는 경우 OmniFaces를 사용할 수 있습니다 .

    <html ... xmlns:o="http://omnifaces.org/ui">
    <o:importConstants type="com.example.YourConstants" />
    

    이렇게하면 일반적인 Javabean 방식으로 #{YourConstants.FOO}액세스 할 수 있습니다.

  5. Javabean 스타일의 getter 메서드를 통해 반환하는 래퍼 클래스를 만듭니다.

  6. 먼저 상수의 존재를 스캔하고없는 경우 기본 해석기에 위임하고 그렇지 않으면 대신 상수 값을 반환하는 사용자 정의 EL 해석기를 만듭니다.


다음은 일반적으로 EL에 적용되지 않지만 대신 SpEL (Spring EL)에만 적용됩니다 (Tomcat 7에서 3.2.2.RELEASE로 테스트 됨). 누군가가 JSP와 EL을 검색하는 경우 (그러나 Spring과 함께 JSP를 사용하는 경우) 여기에서 언급 할 가치가 있다고 생각합니다.

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<spring:eval var="constant" expression="T(com.example.Constants).CONSTANT"/>

일반적으로 이러한 종류의 상수 Configuration는 서블릿 컨텍스트 객체 (게터 및 세터가 있음)에 배치하고 다음을 사용하여 액세스합니다.${applicationScope.config.url}


당신은 할 수 없습니다. Java Bean 규칙을 따릅니다. 그래서 당신은 그것을위한 게터가 있어야합니다.


EL에서는 정적 속성에 액세스 할 수 없습니다. 내가 사용하는 해결 방법은 정적 값에 자신을 할당하는 비 정적 변수를 만드는 것입니다.

public final static String MANAGER_ROLE = 'manager';
public String manager_role = MANAGER_ROLE;

나는 lombok을 사용하여 getter와 setter를 생성하므로 꽤 좋습니다. EL은 다음과 같습니다.

${bean.manager_role}

http://www.ninthavenue.com.au/java-static-constants-in-jsp-and-jsf-el의 전체 코드


나는 다음과 같이 구현했다.

public interface Constants{
    Integer PAGE_SIZE = 20;
}

-

public class JspConstants extends HashMap<String, String> {

        public JspConstants() {
            Class c = Constants.class;
            Field[] fields = c.getDeclaredFields();
            for(Field field : fields) {
                int modifier = field.getModifiers();
                if(Modifier.isPublic(modifier) && Modifier.isStatic(modifier) && Modifier.isFinal(modifier)) {
                    try {
                        Object o = field.get(null);
                        put(field.getName(), o != null ? o.toString() : null);
                    } catch(IllegalAccessException ignored) {
                    }
                }
            }
        }

        @Override
        public String get(Object key) {
            String result = super.get(key);
            if(StringUtils.isEmpty(result)) {
                throw new IllegalArgumentException("Check key! The key is wrong, no such constant!");
            }
            return result;
        }
    }

다음 단계는이 클래스의 인스턴스를 servlerContext에 넣습니다.

public class ApplicationInitializer implements ServletContextListener {


    @Override
    public void contextInitialized(ServletContextEvent sce) {
        sce.getServletContext().setAttribute("Constants", new JspConstants());
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

web.xml에 리스너 추가

<listener>
    <listener-class>com.example.ApplicationInitializer</listener-class>
</listener>

jsp에서 액세스

${Constants.PAGE_SIZE}

처음에 내 jsp에서 상수를 정의하고 있습니다.

<%final String URI = "http://www.example.com/";%>

내 JSP에 핵심 taglib를 포함합니다.

<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>

그런 다음 다음 명령문으로 EL에서 상수를 사용할 수 있도록합니다.

<c:set var="URI" value="<%=URI%>"></c:set>

이제 나중에 사용할 수 있습니다. 다음은 디버깅 목적으로 값이 HTML 주석으로 작성된 예입니다.

<!-- ${URI} -->

상수 클래스를 사용하면 클래스를 가져오고 상수를 로컬 변수에 할당 할 수 있습니다. 내 대답이 일종의 빠른 해킹이라는 것을 알고 있지만 JSP에서 상수를 직접 정의하고 싶을 때도 질문이 올라갑니다.


그래 넌 할수있어. 사용자 정의 태그가 필요합니다 (다른 곳에서 찾을 수없는 경우). 나는 이것을했다 :

package something;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Map;
import java.util.TreeMap;

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

import org.apache.taglibs.standard.tag.el.core.ExpressionUtil;

/**
 * Get all class constants (statics) and place into Map so they can be accessed
 * from EL.
 * @author Tim.sabin
 */
public class ConstMapTag extends TagSupport {
    public static final long serialVersionUID = 0x2ed23c0f306L;

    private String path = "";
    private String var = "";

    public void setPath (String path) throws JspException {
        this.path = (String)ExpressionUtil.evalNotNull ("constMap", "path",
          path, String.class, this, pageContext);
    }

    public void setVar (String var) throws JspException {
        this.var = (String)ExpressionUtil.evalNotNull ("constMap", "var",
          var, String.class, this, pageContext);
    }

    public int doStartTag () throws JspException {
        // Use Reflection to look up the desired field.
        try {
            Class<?> clazz = null;
            try {
                clazz = Class.forName (path);
            } catch (ClassNotFoundException ex) {
                throw new JspException ("Class " + path + " not found.");
            }
            Field [] flds = clazz.getDeclaredFields ();
            // Go through all the fields, and put static ones in a Map.
            Map<String, Object> constMap = new TreeMap<String, Object> ();
            for (int i = 0; i < flds.length; i++) {
                // Check to see if this is public static final. If not, it's not a constant.
                int mods = flds [i].getModifiers ();
                if (!Modifier.isFinal (mods) || !Modifier.isStatic (mods) ||
                  !Modifier.isPublic (mods)) {
                    continue;
                }
                Object val = null;
                try {
                    val = flds [i].get (null);    // null for static fields.
                } catch (Exception ex) {
                    System.out.println ("Problem getting value of " + flds [i].getName ());
                    continue;
                }
                // flds [i].get () automatically wraps primitives.
                // Place the constant into the Map.
                constMap.put (flds [i].getName (), val);
            }
            // Export the Map as a Page variable.
            pageContext.setAttribute (var, constMap);
        } catch (Exception ex) {
            if (!(ex instanceof JspException)) {
                throw new JspException ("Could not process constants from class " + path);
            } else {
                throw (JspException)ex;
            }
        }
        return SKIP_BODY;
    }
}

태그는 다음과 같이 호출됩니다.

<yourLib:constMap path="path.to.your.constantClass" var="consts" />

모든 공개 정적 최종 변수는 해당 Java 이름으로 색인이 생성 된 맵에 배치됩니다.

public static final int MY_FIFTEEN = 15;

그런 다음 태그는 이것을 Integer로 래핑하고 JSP에서 참조 할 수 있습니다.

<c:if test="${consts['MY_FIFTEEN'] eq 15}">

getter를 작성할 필요가 없습니다!


할 수 있습니다. 방법을 따르십시오

 #{T(com.example.Addresses).URL}

TomCat 7 및 java6에서 테스트 됨


조금 늦게 알고 심지어 이것이 약간의 해킹이라는 것을 알고도-원하는 결과를 얻기 위해 다음 솔루션을 사용했습니다. Java-Naming-Conventions 애호가라면 여기에서 읽는 것을 중단하는 것이 좋습니다.

Having a class like this, defining Constants, grouped by empty classes to create kind of a hierarchy:

public class PERMISSION{
    public static class PAGE{
       public static final Long SEE = 1L; 
       public static final Long EDIT = 2L; 
       public static final Long DELETE = 4L; 
       ...
    }
}

can be used from within java as PERMISSION.PAGE.SEE to retrieve the value 1L

To achieve a simliar access-possibility from within EL-Expressions, I did this: (If there is a coding-god - he hopefully might forgive me :D )

@Named(value="PERMISSION")
public class PERMISSION{
    public static class PAGE{
       public static final Long SEE = 1L; 
       public static final Long EDIT = 2L; 
       public static final Long DELETE = 4L; 
       ...

       //EL Wrapper
       public Long getSEE(){
           return PAGE.SEE;
       }

       public Long getEDIT(){
           return PAGE.EDIT;
       }

       public Long getDELETE(){
           return PAGE.DELETE;
       }
    }

    //EL-Wrapper
    public PAGE getPAGE() {
        return new PAGE();
    }
}

finally, the EL-Expression to access the very same Long becomes: #{PERMISSION.PAGE.SEE} - equality for Java and EL-Access. I know this is out of any convention, but it works perfectly fine.


@Bozho already provided a great answer

You usually place these kinds of constants in a Configuration object (which has getters and setters) in the servlet context, and access them with ${applicationScope.config.url}

However, I feel an example is needed so it brings a bit more clarity and spare someone's time

@Component
public Configuration implements ServletContextAware {
    private String addressURL = Addresses.URL;

    // Declare other properties if you need as also add corresponding
    // getters and setters

    public String getAddressURL() {
        return addressURL;
    }

    public void setServletContext(ServletContext servletContext) {
        servletContext.setAttribute("config", this);
    }
}

There is a workaround that is not exactly what you want, but lets you active almost the same with touching scriptlets in a quite minimal way. You can use scriptlet to put value into a JSTL variable and use clean JSTL code later in the page.

<%@ taglib prefix="c"       uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page import="com.whichever.namespace.Addresses" %>
<c:set var="ourUrl" value="<%=Addresses.URL%>"/>
<c:if test='${"http://www.google.com" eq ourUrl}'>
   Google is our URL!
</c:if>

참고URL : https://stackoverflow.com/questions/3732608/how-to-reference-constants-in-el

반응형