JSP / EL'de statik bir yöntem nasıl çağırılır?


88

JSP'de yeniyim. MySQL ile JSP sayfalarımı bağlamayı denedim ve iyi çalışıyor. Ama işte yapmam gereken şey. "Bakiye" adlı bir tablo özelliğim var. Onu alın ve "tutar" adlı yeni bir değer hesaplamak için kullanın. ("Bakiye" yazdırmıyorum).

 <c:forEach var="row" items="${rs.rows}">
        ID: ${row.id}<br/>
        Passwd: ${row.passwd}<br/>
        Amount: <%=Calculate.getAmount(${row.balance})%>
 </c:forEach>

JSTL etiketlerinin içine komut dizileri eklemek mümkün görünmüyor.

Yanıtlar:


133

EL'de doğrudan statik yöntemleri çağıramazsınız. EL yalnızca örnek yöntemlerini çağıracaktır.

Başarısız olan komut dosyası girişiminize gelince , komut dosyalarını ve EL'yi karıştıramazsınız . Birini veya diğerini kullanın. Yana komut dosyası uygulamacıklarını edilir cesaretini bir on yıl içinde, bir EL-tek çözüm bağlı kalmalıdırlar.

Temelde 2 seçeneğiniz var (hem varsayarak balanceve Calculate#getAmount()vardır double).

  1. Sadece bir örnek yöntemine sarın.

    public double getAmount() {
        return Calculate.getAmount(balance);
    }
    

    Ve bunun yerine kullanın:

    Amount: ${row.amount}
    

  2. Veya Calculate#getAmount()EL işlevi olarak ilan edin . Önce bir /WEB-INF/functions.tlddosya oluşturun :

    <?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">
    
        <display-name>Custom Functions</display-name>    
        <tlib-version>1.0</tlib-version>
        <uri>http://example.com/functions</uri>
    
        <function>
            <name>calculateAmount</name>
            <function-class>com.example.Calculate</function-class>
            <function-signature>double getAmount(double)</function-signature>
        </function>
    </taglib>
    

    Ve aşağıdaki gibi kullanın:

    <%@taglib uri="http://example.com/functions" prefix="f" %>
    ...
    Amount: ${f:calculateAmount(row.balance)}">
    

@BalusC Ya jsp'mde bir değer varsa (hesaplamışsa) ve bunu bir parametre olarak göndermek istersem ??
Sriram

7
@Sriram: Öncelikle, JSP'yi HTML / JS ile karıştırmadığınızdan emin misiniz? Soruyu ortaya koyma şekliniz, JSP'nin web tarayıcısında çalıştığını düşündüğünüzü, ancak bu tamamen doğru olmadığını gösteriyor. JSP, bir HTML / CSS / JS kod üreticisidir. Bu kadar. Bu size sorunuz ve yaklaşımınız hakkında düşünmeniz için bir şeyler vermelidir.
BalusC

aradığım şey :)
aliopi

@PhilipRego: cevaptaki kod sadece söz konusu koda dayanmaktadır.
BalusC

61

Başka bir yaklaşım da Spring SpEL'i kullanmaktır:

<%@taglib prefix="s" uri="http://www.springframework.org/tags" %>

<s:eval expression="T(org.company.Calculate).getAmount(row.balance)" var="rowBalance" />
Amount: ${rowBalance}

İsteğe bağlı atlarsanız var="rowBalance"sonra <s:eval>çıkışa ifadenin sonucunu yazdırır.


bu daha da iyi! diğerleri için, \ "the_string_argument \" ekleyerek (row.balance bölümü yerine) statik yöntemde bir dize sağlayabilirsiniz. Bu, yalnızca yönteminiz dizeleri hariç tutuyorsa geçerlidir. ;) Şerefe!
despot

3
Dizeleri tek tırnak içinde iletebilirsiniz, örneğin 'the_string_argument'- kaçarak dans etmeye gerek yoktur.
dma_k

Harika, bu benim için ilkbaharda işe yaradı ... 2 sınıf yapmanın mümkün olup olmadığını merak ettim ... sadece clas'a bir T () önek eklemem gerekiyor sanırım ... Bu yaptığım şey için çalıştı: < s: eval expression = "T (org.jsoup.Jsoup) .clean (orig_text, T (org.jsoup.safety.Whitelist) .none ())" var = "text_stripped_html" /> şuna eşdeğer: String text_stripped_html = Jsoup. clean (orig_text, Whitelist.none ());
armyofda12mnkeys

@msangel: Bu konudaki diğer yanıtları kontrol edin.
dma_k

5

Java sınıfınız şuysa:

package com.test.ejb.util;

public class CommonUtilFunc {

    public static String getStatusDesc(String status){

        if(status.equals("A")){
            return "Active";
        }else if(status.equals("I")){
            return "Inactive";
        }else{
            return "Unknown";
        }
    }
}

Daha sonra JSP sayfasında aşağıdaki gibi 'getStatusDesc' statik yöntemini çağırabilirsiniz.

Sınıfı JSP sayfasının en üstüne almak için JSTL useBean kullanın:

<jsp:useBean id="cmnUtilFunc" class="com.test.ejb.util.CommonUtilFunc"/>

Ardından, İfade Dilini kullanarak istediğiniz yerde işlevi çağırın:

<table>
    <td>${cmnUtilFunc.getStatusDesc('A')}</td>
</table>

Bu benim için faydalı. Harika!!
Abu Bakar Siddik

4

Bean gibi StaticInterface de kullanılabilir

<h:commandButton value="reset settings" action="#{staticinterface.resetSettings}"/>

ve fasulye

package com.example.common;

import com.example.common.Settings;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;

@ManagedBean(name = "staticinterface")
@ViewScoped
public class StaticInterface {

    public StaticInterface() {
    }

    public void resetSettings() {
        Settings.reset();
    }
}

Kodda, sınıf adında "Statik" dışında herhangi bir statik anahtar kelime göremiyorum.
Uluk Biy

2
@UlukBiy, Settings.reset()statik bir yöntem çağrısıdır. Lukas, EL'den çağırmak istediği her statik yöntem için statik olmayan bir yöntemle sarmalayıcı benzeri bir ManagedBean oluşturmayı önerir. Bu geçerli bir çözüm.
Vsevolod Golovanov

3

EL 2.2, yöntemleri çağırmak için dahili bir mekanizmaya sahiptir. Daha fazlası burada: oracle sitesi . Ancak statik yöntemlere erişimi yoktur. Yine de nesne referansı yoluyla çağırabilirsiniz. Ancak bu makalede açıklanan başka bir çözüm kullanıyorum: EL'den Statik Yöntemi Çağırma


1
EL 2.2'nin statik bir yöntemi çağırmak için gerçekten yerleşik bir destek eklediğini düşünüyorum. Çözümler, bir fasulyeyi talep bağlamlarına yerleştirmeye ve (çirkin) öykünmelere, bir harita + gerekli parametreler referans alma sırasında geçirilmesine dayanır. Bu yaklaşımın ek yükü, talep bağlamına (örneğin, içinde <web-app> → <filter>) masaj yapılması gerektiğidir .
dma_k

2

Struts2 kullanıyorsanız, kullanabilirsiniz

<s:var name='myVar' value="%{@package.prefix.MyClass#myMethod('param')}"/>

ve sonra html veya html etiket özniteliğinde "myVar" a şu şekilde referansta bulunun: ${myVar}


1
Askerin söylediği gibi payandalar JSP değildir.
bogdan.mustiata

2

@Lukas cevabına dayanarak, bu fasulyeyi ve çağrı yöntemini yansıtarak kullanabilirsiniz:

@ManagedBean (name = "staticCaller")
@ApplicationScoped
public class StaticCaller {
private static final Logger LOGGER = Logger.getLogger(StaticCaller.class);
/**
 * @param clazz
 * @param method
 * @return
 */
@SuppressWarnings("unchecked")
public <E> E call(String clazz, String method, Object... objs){
    final ClassLoader loader = Thread.currentThread().getContextClassLoader();
    final List<Class<?>> clasesparamList = new ArrayList<Class<?>>();
    final List<Object> objectParamList = new ArrayList<Object>();
    if (objs != null && objs.length > 0){
        for (final Object obj : objs){
            clasesparamList.add(obj.getClass());
            objectParamList.add(obj);
        }
    }
    try {           
        final Class<?> clase = loader.loadClass(clazz);
        final Method met = clase.getMethod(method, clasesparamList.toArray(new Class<?>[clasesparamList.size()]));
            return (E) met.invoke(null, objectParamList.toArray());
        } catch (ClassNotFoundException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (InvocationTargetException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (IllegalAccessException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (IllegalArgumentException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (NoSuchMethodException e) {
            LOGGER.error(e.getMessage(), e);
        } catch (SecurityException e) {
            LOGGER.error(e.getMessage(), e);
        }
        return null;
    }
}

xhtml, örneğin bir komut düğmesine:

<p:commandButton action="#{staticCaller.call('org.company.Calculate', 'getAmount', row.balance)}" process="@this"/>

EL (2.2) yöntem ifadelerinde değişken argümanlar kullanmak mümkün değildir.
Robert Kornmesser

Merhaba Robert, özür dilerim tam olarak ne demek istiyorsun, bu kodu uzun zamandır kullandım ve eminim işe yarıyor. Hatam nerede
Juan

Gerçek özellikleri bulamıyorum, ancak BalusC'nin burada bahsettiği gibi stackoverflow.com/questions/15560508/… nedeni budur SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (http-localhost/127.0.0.1:8080-5) java.lang.IllegalArgumentException: wrong number of arguments.
Robert Kornmesser

Evet, EL üzerinde değişken bağımsız değişkenler kullanamazsınız. Ancak bu yöntemi EL'den kullanabilirsiniz. Son argüman olarak bir dizi geçirerek kullanılabilir. Bu durumda gerekli değildir çünkü son argüman olarak iletilen sadece bir nesne vardır.
Juan

1
<c:forEach var="row" items="${rs.rows}">
        ID: ${row.id}<br/>
        Passwd: ${row.passwd}<br/>
<c:set var="balance" value="${row.balance}"/>
        Amount: <%=Calculate.getAmount(pageContext.getAttribute("balance").toString())%>
 </c:forEach>

Bu çözümde, bir değişkene değer (Çekirdek etiket aracılığıyla) atıyoruz ve ardından bu değişkenin değerini komut dosyasında alıyoruz.


0

Struts2 veya Webwork2'de bunu kullanabilirsiniz:

<s:set name="tourLanguage" value="@foo.bar.TourLanguage@getTour(#name)"/>

Sonra #tourLanguagejsp'nizdeki referans

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.