Как получить класс public string в JSP? [Дубликат]

Попробуйте https://github.com/fotuzlab/appgati

Он позволяет определять шаги в коде и время отчетов, использование памяти, загрузку сервера и т. д. между двумя шагами .

Что-то вроде:

    $appgati->Step('1');

    // Do some code ...

    $appgati->Step('2');

    $report = $appgati->Report('1', '2');
    print_r($report);

Пример массива вывода:

Array
(
    [Clock time in seconds] => 1.9502429962158
    [Time taken in User Mode in seconds] => 0.632039
    [Time taken in System Mode in seconds] => 0.024001
    [Total time taken in Kernel in seconds] => 0.65604
    [Memory limit in MB] => 128
    [Memory usage in MB] => 18.237907409668
    [Peak memory usage in MB] => 19.579357147217
    [Average server load in last minute] => 0.47
    [Maximum resident shared size in KB] => 44900
    [Integral shared memory size] => 0
    [Integral unshared data size] => 0
    [Integral unshared stack size] => 
    [Number of page reclaims] => 12102
    [Number of page faults] => 6
    [Number of block input operations] => 192
    [Number of block output operations] => 
    [Number of messages sent] => 0
    [Number of messages received] => 0
    [Number of signals received] => 0
    [Number of voluntary context switches] => 606
    [Number of involuntary context switches] => 99
)

95
задан BalusC 11 March 2016 в 09:25
поделиться

12 ответов

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 + работают.

Этот объект доступен только в JSP, а не в Facelets. В случае JSF + Facelets лучше всего использовать OmniFaces <o:importConstants> , как показано ниже:

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

Или добавить прослушиватель контекста EL, который вызывает ImportHandler#importClass(), как показано ниже:

@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 значения карты доступны обычным javabean способом ${map.key} или ${map['key.with.dots']}.
  2. Используйте <un:useConstants> в Unstandard taglib ( maven2 repo здесь ):
    <%@ taglib uri="http://jakarta.apache.org/taglibs/unstandard-1.0" prefix="un" %>
    <un:useConstants className="com.example.YourConstants" var="constants" />
    
    Таким образом, они доступны обычным javabean способом ${constants.FOO}.
  3. Используйте Javaranch's CCC <ccc:constantsMap> as описал где-то внизу эту статью .
    <%@ 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. Создайте класс-оболочку, который возвращает их с помощью методов getter в стиле Javabean.
  6. Создайте пользовательский EL, который сначала сканирует наличие константы и, если отсутствует, затем делегирует значение по умолчанию, вместо этого возвращает константное значение.
146
ответ дан BalusC 17 August 2018 в 12:21
поделиться
  • 1
    Я нашел этот вопрос, потому что у меня была такая же проблема при попытке использовать статическое поле List с тегом form: options. Я смог заставить его работать, добавив нестатический getter, который возвращает статический список. Это немного глупо, но эй, это JSP-разработка для тебя! – spaaarky21 1 November 2011 в 21:56
  • 2
    Есть ли у вас пример, как настроить это для JSF, если beans управляется весной? Thx заранее. – Lodger 20 November 2013 в 22:48
  • 3
    @Lodger: Я не делаю весну. – BalusC 20 November 2013 в 22:55
  • 4
    Является ли проект jakarta unstandard-taglib еще живым? есть ли альтернатива? – davioooh 25 June 2014 в 08:43
  • 5
    Есть ли способ использовать эти методы для перечислений? – Niklas Peter 24 December 2015 в 10:13

Вы не можете. Это следует за соглашением Java Bean. Поэтому у вас должен быть геттер.

5
ответ дан Adeel Ansari 17 August 2018 в 12:21
поделиться

Я реализовал как:

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}
4
ответ дан Alexander Kjäll 17 August 2018 в 12:21
поделиться

В EL обычно не применяется, но вместо этого используется только SpEL (Spring EL) (протестировано с 3.2.2.RELEASE на Tomcat 7). Я думаю, что стоит упомянуть об этом здесь, если кто-то ищет JSP и EL (но использует JSP с Spring).

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<spring:eval var="constant" expression="T(com.example.Constants).CONSTANT"/>
8
ответ дан anre 17 August 2018 в 12:21
поделиться

Существует обходное решение, которое не совсем то, что вам нужно, но позволяет вам практически не реагировать на прикосновение к скриптлетам весьма минимальным образом. Вы можете использовать скриптлет, чтобы поместить значение в переменную JSTL и использовать чистый код JSTL позже на странице.

<%@ 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>
0
ответ дан Artem 17 August 2018 в 12:21
поделиться

Вы обычно размещаете эти типы констант в объекте Configuration (который имеет геттеры и сеттеры) в контексте сервлета и обращаются к ним с помощью ${applicationScope.config.url}

8
ответ дан Bozho 17 August 2018 в 12:21
поделиться
  • 1
    Немного новичок здесь, когда дело доходит до jsp's - не могли бы вы объяснить это более полно? – tau-neutrino 17 September 2010 в 05:33
  • 2
    @ tau-neutrino: На самом деле это просто. Создайте класс с url как свойство String, назовите его Configuration, создайте экземпляр и установите url в любое удобное для вас время. После этого установите Configuration объект в ServletContext. Сделайте что-нибудь вроде servletContext.setAttribute("config", config). И вот ты туда. – Adeel Ansari 17 September 2010 в 12:10
  • 3
    В чем разница между предлагаемым решением и просто добавлением константы как атрибута ServletContext? Это просто, что вы можете более аккуратно классифицировать константы? например: applicationScope.config.url против applicationScope.url. – theyuv 8 August 2017 в 14:58

Вы можете. Попробуйте следовать

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

Протестировано на TomCat 7 и java6

2
ответ дан Dmytro Boichenko 17 August 2018 в 12:21
поделиться
  • 1
    Это похоже на SpEL, а не на EL. Я ошибаюсь? Кроме того, будет ли это работать в более старом Tomcat5.5? – Pytry 18 March 2014 в 18:50

Даже зная его немного поздно, и даже зная, что это немного взломать, я использовал следующее решение для достижения желаемого результата. Если вы любите Java-Naming-Conventions, мой совет состоит в том, чтобы прекратить чтение здесь ...

Имея такой класс, определяя константы, сгруппированные пустыми классами, чтобы создать вид иерархии:

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; 
       ...
    }
}

можно использовать из java как PERMISSION.PAGE.SEE для извлечения значения 1L

. Для достижения простой возможности доступа из EL-выражений я сделал следующее: (Если есть бог кодирования - он, надеюсь, может простить меня: 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();
    }
}

, наконец, EL-Expression для доступа к тому же самому Long становится: #{PERMISSION.PAGE.SEE} - равенство для Java и EL-Access. Я знаю, что это вне всякого соглашения, но оно отлично работает.

1
ответ дан dognose 17 August 2018 в 12:21
поделиться

Я определяю константу в jsp прямо в начале:

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

Я включаю основной теглиб в свой JSP:

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

Затем я делаю константа, доступная для EL посредством следующего утверждения:

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

Теперь я могу использовать его позже. Здесь пример, где значение просто написано как комментарий HTML для целей отладки:

<!-- ${URI} -->

С вашим постоянным классом вы можете просто импортировать свой класс и назначить константы локальным переменным. Я знаю, что мой ответ - это своего рода быстрый взлом, но вопрос также возникает, когда нужно определить константы непосредственно в JSP.

1
ответ дан koppor 17 August 2018 в 12:21
поделиться
  • 1
    lol почему бы не использовать Scriptlets напрямую, если это так, как вы инициализируете переменные EL? – Navin 11 October 2015 в 09:44
  • 2
    Три строки сверху - беспорядок, а затем очищают EL во всей остальной части JSP ^^. – koppor 11 October 2015 в 17:54
  • 3
    @koppoor Я так думаю. Я просто собираюсь использовать <%=URI%>: P – Navin 12 October 2015 в 00:09

@Bozho уже предоставил отличный ответ

Обычно вы размещаете эти типы констант в объекте Configuration (который имеет геттеры и сеттеры) в контексте сервлета и получаете к ним доступ с помощью $ {applicationScope .config.url}

Тем не менее, я чувствую, что нужен пример, чтобы он приносил немного большей ясности и оставлял чье-то время

@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);
    }
}
1
ответ дан lunohodov 17 August 2018 в 12:21
поделиться

Статические свойства недоступны в 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

4
ответ дан Roger Keays 17 August 2018 в 12:21
поделиться

Да, вы можете. Вам нужен специальный тег (если вы не можете найти его где-то еще). Я сделал это:

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}">

, и вам не нужно писать геттеры!

2
ответ дан Tim Sabin 17 August 2018 в 12:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: