2012-11-28 9 views
7

Mam aplikację Struts 2 (JDK 1.7, Struts 2.2.1), która zawiera listę kryteriów filtrowania przechowywanych jako ciągi na mapie.Dlaczego Struts2 przekształca mój ciąg na tablicę ciągów?

Map< String, String > m_filters = new HashMap< String, String >(); 

public Map< String, String > getFilters() { 
    return m_filters; 
} 

mijam URL sformatowany tak:

http://myserver.com/myapp/GenerateReport.action?reportID=Whatever&filters.fromDate=0&filters.toDate=2000000000&filters.FcsType=piv_cardholder_3kp&detailed=true

Mimo że mapa ma zarówno główne typy & wartość określona jako String, próbując uzyskać wartość z tego

Map< String, String > filters = getFilters(); 
    String value = filters.get("fromDate"); 

powoduje wyrzucenie tego wyjątku:

java.lang.ClassCastException: [Ljava.lang.String; cannot be cast to java.lang.String

Odtworzyłem to w teście jednostkowym i potwierdziłem w debugerze, że Struts 2 wydaje się tworzyć String [1] zamiast String dla każdego z parametrów. to jest tablica ciągów o długości 1, przy czym jedynym ciągiem jest oczekiwana wartość (w tym przypadku "0").

Moje pytanie brzmi: Czy to błąd w Struts2, czy robię coś niepoprawnie?

Jeśli jest to błąd, czy istnieje znane obejście tego problemu?

+0

Czy możesz wypróbować wartość ciągu = (java.lang.String) filters.get ("fromDate"); i biegnij? –

+0

Problem polega na tym, że mapa zawiera ciągi znaków [], a nie ciągi znaków, mimo że są sparametryzowane (sp?) Za pomocą , więc wyraźny rzut nadal będzie powodował błąd. –

+1

+1 btw, ponieważ to było interesujące Nie jestem pewien, czy zachowanie struts2 w tym przypadku jest najbardziej sensowne. To prawda, że ​​powinieneś przestrzegać konwencji, ale prawdą jest również, że to, czego doświadczasz, nie jest intuicyjne. – Quaternion

Odpowiedz

6

Nie ma problemów, jeśli postępujesz zgodnie z zasadami Java bean.

Oto kilka wskazówek, aby rozwiązać ten problem:

  • Ten problem nie stanie, jeśli nazwać prywatnym Państwa „filtra” i dostarczyć tylko getter dla filtra.
  • Ten problem nie stanie, jeśli podasz publiczny setter (nawet jeśli używasz innej nazwy dla członka prywatnych, takich jak m_filter) w uzupełnieniu do getter
  • ten problem tylko się dzieje, jeśli nie zapewniają setter i właściwość nie ma tej samej nazwy co getter.

Konwencje z krótkimi historiami. Powyżej zachowań badanego z Struts 2.3.4

Co Zgaduję dzieje: getter pozwala na ustawienie zbyt (jeśli nie było tylko seter można ustawić tylko jedną pozycję na mapie, dobrze z obecnym parametrze przechwytywacz w tym przypadku). Komponent bean jest sprawdzany pod kątem właściwości, aby przekonać się, jak powinien on przeprowadzić konwersję typu, prawdopodobnie najpierw szuka ustawionego błędu, który sprawdza działanie pod kątem tej właściwości, aby określić błąd typu, który będzie wymagał użycia wartości domyślnej. Domyślnym typem parametru jest odwzorowanie ciągu znaków na ciąg [] i właśnie to widzisz.

+0

Zgadzam się. @Shawn D .: Twórz poprawne programy pobierające/ustawiające i powinno działać. –

+0

@ShawnD Czy próbowałeś sugestii Quaternion? Czy to działa dla ciebie? –

+0

To było to. Doszedłem do wniosku, że nie potrzebowałem setera dla mapy, ponieważ został on wstępnie przydzielony, więc Struts2 nie musiał go tworzyć. Jednak bez ustawiacza, * nawet jeśli nigdy nie wywołuje settera *, nie wie, jakiego typu użyć dla mapy i dlatego przekazuje go jako tablicę ciągów. Dobry połów. –

0

Spróbuj tego:

Object[] obj = (Object[]) filters.get("fromDate"); 
String value = (String)obj[0]); 
0

To nie jest bug można uznać, że jest to cecha. Access RequestParameters

ParameterAware Interceptor

Załóżmy /http://localhost:8080/myApp/login.action?name=struts2 & name = skały

jeśli spróbujesz otworzyć ciąg nazwa parametru [0 ] = struts2, string 1 = rocks

+0

Oba parametry mają tę samą nazwę. Moje powinny być wpisami pod tą samą mapą z różnymi kluczami. filters.fromDate jest unikalnym kluczem na liście parametrów. –

+0

Według mojego zrozumienia parametr struts2 Zaprojektowany w taki sposób, aby poradzić sobie z powyższą sytuacją. –

+1

Parametr wygląda tak, jakby ktoś potrzebował dostępu do wszystkich parametrów żądania. W moim przypadku próbuję określić, dlaczego przekazywanie pojedynczego ciągu, nawet jeśli nie ma innych parametrów, zostaje przekształcone w tablicę ciągów o długości 1. –

4

Używasz niewłaściwej notacji. filters.fromDate będzie odpowiednikiem getFilters().setFromDate(), co w rzeczywistości nie jest tym, czego potrzebujesz. Notacja Dot jest dla JavaBeans.

Spróbuj użyć nawiasów, takich jak filters['fromDate'].

Patrz: http://struts.apache.org/2.2.1/docs/type-conversion.html#TypeConversion-RelationshiptoParameterNames.

+1

Ten sam wynik (ClassCastException) z filtrami ['fromDate']. Uważam, że notacja kropek jest ważna dla Map, ponieważ jest używana jako klucz, chyba że odpowiada specjalnej wartości (np.. Rozmiar, która zwraca rozmiar mapy). Po prostu nie mogę teraz znaleźć tego odniesienia. –

+0

Nie wiesz, co powiedzieć. Zaktualizowałem Mapy wcześniej z konwencją nawiasów bez problemu. :/ –

+0

@StevenBenitez: Mapy są dostępne z obu notacji. Na przykład. zobacz odwołanie do 'sesji' tutaj http://struts.apache.org/2.x/docs/ognl.html. –

Powiązane problemy