Как получить значение карты с помощью нулевого ключа внутри JSP

У меня есть Map<Integer, Object>, переданный в JSP с контроллера. Имеется нулевой ключ со значением по умолчанию, это означает, что map.get(null) возвращает объект по умолчанию. keyObject.keyProp является целым числом и может иметь значение NULL.

Когда я использую это в jsp

<c:out value="${map[keyObject.keyProp]}"/>

Я не получаю никаких результатов для нулевых ключей. Есть ли способ заставить нулевые ключи работать в jsp?


person kenor    schedule 17.01.2013    source источник
comment
что keyProp? где он создан?   -  person Eliran Malka    schedule 18.01.2013
comment
btw Похоже, вы пропустили EL eval-выражение, то есть ${expr} или #{expr}. Вы говорите, что передали карту в JSP от контроллера (сервлета). Возможно вы установили атрибут (запрос или другой). Затем для доступа к вашей карте в JSP вы должны использовать язык выражений (использование скриптов крайне не рекомендуется)   -  person informatik01    schedule 18.01.2013
comment
Обновил свой ответ простым примером.   -  person informatik01    schedule 18.01.2013


Ответы (1)


Похоже, что единственный способ получить значение для ключа null с использованием стандартной реализации EL - это вызвать метод get() на карте (учитывая, что вы сказали, что keyObject.keyProp разрешается в объект Integer ):

<c:out value="${map.get(keyObject.keyProp)}" />

Я протестировал это решение, и оно работает.

На самом деле, в этом случае вы легко можете обойтись без <c:out />, просто используйте простой EL там, где он вам нужен, например

${map.get(keyObject.keyProp)}

Простой пример:

TestMapServlet.java

package com.example;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

import java.util.Map;
import java.util.HashMap;

import java.io.IOException;

public class TestMapServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response)
                    throws ServletException, IOException {
        Map<Integer, Object> map = new HashMap<Integer, Object>();
        Integer noValueInt = null;
        Integer one = new Integer(1);
        Integer two = new Integer(2);

        map.put(noValueInt, "Default object for null Integer key");
        map.put(one, "Object for key = Integer(1)");
        map.put(two, "Object for key = Integer(2)");

        request.setAttribute("map", map);
        request.setAttribute("noValueInt", noValueInt);
        request.setAttribute("one", one);
        request.setAttribute("two", two);

        request.getRequestDispatcher("/test-map.jsp").forward(request, response);
    }
}


test-map.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<!DOCTYPE html>
<html>
<head>
    <title>Home Page</title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
    <h1>Testing access to java.util.Map using just EL</h1>
    <p><b>\${map.get(noValueInt)}</b>: ${map.get(noValueInt)}</p>
    <p><b>\${map[one]}</b>: ${map[one]}</p>
    <p><b>\${map[two]}</b>: ${map[two]}</p>

    <h1>Testing access to java.util.Map using JSTL and EL</h1>
    <p><b>&lt;c:out value="\${map.get(noValueInt)}" /&gt; </b>: <c:out value="${map.get(noValueInt)}" /></p>
    <p><b>&lt;c:out value="\${map[one]}" /&gt; </b>: <c:out value="${map[one]}" /></p>
    <p><b>&lt;c:out value="\${map[two]}" /&gt; </b>: <c:out value="${map[two]}" /></p>

    <h2>Printing java.util.Map keys and values (when Key = null, the <i>null</i> won't be shown)</h2>
    <c:forEach items="${map}" var="entry">
        <p><b>Key</b> = "${entry.key}", <b>Value</b> = "${entry.value}"</p>
    </c:forEach>
</body>
</html>


web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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-app_3_0.xsd"
    version="3.0">

    <servlet>
        <servlet-name>Test Map Servlet</servlet-name>
        <servlet-class>com.example.TestMapServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Test Map Servlet</servlet-name>
        <url-pattern>/TestMap.do</url-pattern>
    </servlet-mapping>

</web-app>


ВАЖНОЕ ПРИМЕЧАНИЕ
Чтобы иметь возможность вызывать методы с аргументами с помощью EL, вы должны использовать как минимум сервлет версии 3.0.
Цитата отсюда: https://stackoverflow.com/tags/el/info

Начиная с EL 2.2, который поддерживается как часть Servlet 3.0 / JSP 2.2 (Tomcat 7, Glassfish 3, JBoss AS 6 и т. Д.), Можно при необходимости вызывать методы, не являющиеся геттерами, с аргументами.


Помимо вышеуказанного решения вы можете использовать собственную реализацию единого языка выражений, например JUEL, у которого есть альтернативное решение.

объяснение того, почему невозможно (в стандартной реализации) получить доступ к значению map с помощью null ключа с помощью [], и пользовательское решение может быть содержится в документации Java Unified Expression Language (JUEL) (выделено в абзацы мои):

2.5. Расширенные темы

...

Включение / отключение нулевых свойств

The EL specification describes the evaluation semantics of base[property]. If property is null, the specification states not to resolve null on base. Rather, null should be returned if getValue(...) has been called and a PropertyNotFoundException should be thrown else. As a consequence, it is impossible to resolve null as a key in a map. However, JUEL's expression factory may be configured to resolve null like any other property value. To enable (disable) null as an EL property value, you may set property javax.el.nullProperties to true (false).

Предположим, что карта идентификаторов преобразуется в java.util.Map.

  • Если функция javax.el.nullProperties была отключена, оценка ${base[null]} как rvalue (lvalue) вернет null (вызовет исключение).

  • Если функция javax.el.nullProperties была включена, оценка ${base[null]} как rvalue (lvalue) даст (поместит) значение для ключа null на этой карте. По умолчанию значение NULL в качестве значения свойства EL не допускается.

...

Надеюсь, это поможет.

person informatik01    schedule 17.01.2013
comment
Отличный ответ. Спасибо. - person kenor; 18.01.2013