2017-01-13 9 views
5

Я использую Spring 3.2.11.RELEASE с JBoss 7.1.3.Final и Java 6. У меня есть этот метод в контроллереКак перебрать все атрибуты моей модели на моей странице JSP?

@RequestMapping(value = "/method", method = RequestMethod.GET) 
public String myMethod(final Model model, 
         final HttpServletRequest request, 
         final HttpServletResponse response, 
         final Principal principal) 

... 
    model.addAttribute("paramName", "paramValue"); 

Обратите внимание, как я добавить атрибуты в моей модели. Мой вопрос заключается в том, что на странице JSP, на которой работает эта страница, как я могу перебирать все атрибуты в моей модели и выводить их как поля ввода HIDDEN с именем INPUT, являющимся именем атрибута, и значением, которое я вставлял в используя этот атрибут?

Редактировать: В ответ на предоставленный ответ здесь был представлен выход в решение JSP. Заметьте, что нет атрибутов модели.

 <input type='hidden' name='javax.servlet.jsp.jspRequest' value='org.spring[email protected]7a0a4c3f'> 

     <input type='hidden' name='javax.servlet.jsp.jspPageContext' value='[email protected]'> 

     <input type='hidden' name='appVersion' value='???application.version???'> 

     <input type='hidden' name='javax.servlet.jsp.jspResponse' value='[email protected]'> 

     <input type='hidden' name='javax.servlet.jsp.jspApplication' value='[email protected]'> 

     <input type='hidden' name='org.apache.taglibs.standard.jsp.ImplicitObjects' value='[email protected]c27a49'> 

     <input type='hidden' name='javax.servlet.jsp.jspOut' value='[email protected]'> 

     <input type='hidden' name='javax.servlet.jsp.jspPage' value='[email protected]'> 

     <input type='hidden' name='javax.servlet.jsp.jspConfig' value='[email protected]'> 

ответ

2

Атрибуты модели - это объекты «область запроса» вы можете сделать следующее (я использую JSTL):

<c:forEach items="${requestScope}" var="par"> 
     <c:if test="${par.key.indexOf('attrName_') > -1}"> 
      <li>${par.key} - ${par.value}</li> 
     </c:if> 
    </c:forEach> 

Так, без фильтра вы будете иметь все объекты области запроса, я фильтруюсь атрибуты модели мы хотели проверить

Я проверил, используя этот код:

@RequestMapping(method = { RequestMethod.GET }, value = { "/*" }) 
    public String renderPage(Model model) throws Exception 
    { 
     String requestedUrl = req.getRequestURI(); 
     int indice = requestedUrl.lastIndexOf('/'); 
     String pagina = requestedUrl.substring(indice + 1); 
     try 
     { 
      String usernameUtente = "default username utente"; 
      if (StringUtils.hasText(getPrincipal())) 
      { 
       usernameUtente = getPrincipal(); 
      } 
      model.addAttribute("usernameUtente", usernameUtente); 
      model.addAttribute("webDebug", webDebug); 
      for(int i = 0; i<10; i++) 
      { 
       model.addAttribute("attrName_"+i, "attrValue_"+i); 
      } 
      return pagina; 
     } 
     catch (Exception e) 
     { 
      String message = "Errore nell'erogazione della pagina " + pagina; 
      logger.error(message, e); 
      return "genericError"; 
     } 
    } 

И это то, что я вижу в качестве вывода (я пропустил не соответствующие отпечатки, но обратите внимание, что вы распечатаете ВСЕ объекты области запроса:

attrName_0 - attrValue_0 
attrName_1 - attrValue_1 
attrName_2 - attrValue_2 
attrName_3 - attrValue_3 
attrName_4 - attrValue_4 
attrName_5 - attrValue_5 
attrName_6 - attrValue_6 
attrName_7 - attrValue_7 
attrName_8 - attrValue_8 
attrName_9 - attrValue_9 

Я надеюсь, что это может помочь

Angelo

+0

Это выглядит очень хорошо. Вопрос один, в вашем решении все атрибуты должны начинаться со специального префикса, чтобы это работало? Какой другой нежелательный файл будет распечатан на странице, если я не фильтрую префиксом? – Dave

+0

Ну, у всех атрибутов есть свой ключ; к сожалению, я не знаю всех атрибутов, поскольку некоторые из них могут быть добавлены сервером приложений, другие - с помощью инфраструктуры приложения (например, весны) и других пользователей ... Поэтому лучше всего, может быть, поставить префикс для всех ваших атрибутов и фильтровать только для этих –

+0

Невозможно узнать, какие из них были добавлены JBoss и Spring? – Dave

-1

Вы можете попробовать это:

@RequestMapping(value = "/method", method = RequestMethod.GET) 
public String myMethod(final Model model, 
         final HttpServletRequest request, 
         final HttpServletResponse response, 
         final Principal principal) 

... 
    //Create list for param names and another list for param values 
    List<String> paramNames = new ArrayList(); 
    List<String> paramValues = new ArrayList(); 
    paramNames.add("paramName1"); 
    paramValues.add("paramValue1"); 
    paramNames.add("paramName2"); 
    paramValues.add("paramValue2"); 
    //paramValue1 is the value corresponding to paramName1 and so on... 
    //add as many param names and values as you need 
    ... 
    //Then add both lists to the model 
    model.addAttribute("paramNames", paramNames); 
    model.addAttribute("paramValues", paramValues); 

Тогда в JSP, вы можете перебрать список paramNames и использовать varStatus.index, чтобы получить индекс текущего раунда итерации и использовать его для вытащите значение соответствующего значения параметра из списка paramValues. Как это -

<form id='f' name='myform' method='POST' action='/path/to/servlet'> 
    <c:forEach items="${paramNames}" var="paramName" varStatus="status">  
    <input type='hidden' name='${paramName}' value='${paramValues[status.index]}'> 
    </c:forEach> 
</form> 

Вы можете добавить другие элементы ввода в форму по мере необходимости, но выше, должны генерировать все скрытые элементы ввода для каждого из параметров, которые вы установили в модели.

+0

Для этого требуется дополнительная структура данных, поэтому каждый раз, когда я добавляю новый атрибут модели, мне также нужно добавить его имя параметра в новую структуру данных, так? – Dave

+0

Как показано в ответе выше, вам нужно будет добавить имя параметра и значение параметра в двух отдельных списках. Вам нужно только добавить эти имена и значения параметров в списки, для которых вы хотите создать скрытый элемент ввода. Поскольку вы добавляете эти списки в атрибуты модели, как показано выше, вам не нужно добавлять имена параметров непосредственно к атрибутам модели. Попробуйте, если приведенный выше пример работает для вас, показывает, как это сделать, а затем как перебирать два списка для создания входных элементов со скрытым типом поля. – lazyPanda

+0

Идея состоит в том, что мне нужно только добавить эти пары имя-значение один раз, в одном месте. Я хочу, чтобы скрытые входы были точно такими, которые хранятся в моей модели. Если я собираюсь вести отдельный список, я мог бы просто добавить новый ввод на страницу каждый раз, когда я добавлю что-то в свою модель. – Dave

1

В сущности, все, что вам нужно, это повторить все атрибуты страницы. В зависимости от того, что вы используете на JSP (скриптлеты, JSTL или smthing как thymeleaf для HTML):

скриптлета:

<form> 
    <% Session session = request.getSession(); 
    Enumeration attributeNames = session.getAttributeNames(); 
    while (attributeNames.hasMoreElements()) { 
     String name = attributeNames.nextElement(); 
     String value = session.getAttribute(name); 
    %> 
     <input type='hidden' name="<% name %>" value="<% value %>"> 
    <% 
     } 
    %> 
</form> 

JSTL:

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

<h3>Page attributes:</h3> 
<form> 
    <c:forEach items="${pageScope}" var="p"> 
     <input type='hidden' name='${p.key}' value='${p.value}'> 
    </c:forEach> 
</form> 

Thymeleaf:

<form> 
    <input th:each="var : ${#vars}" type='hidden' name="${var.key}" value="${var.value}"> 
</form> 
+0

Я пробовал решение JSTL (выход включен в мой вопрос). Я хочу, чтобы вы поняли мой вопрос, прежде чем я предпримлю какое-то необдуманное действие. Я ищу атрибуты модели. То, что выводится, не является атрибутом модели. Имеет ли это смысл? – Dave

0

Просто можно перебирать с помощью Еогеаспа тега JSTL.

<c:forEach items="${requestScope}" var="var"> 
    <c:if test="${ !var.key.startsWith('javax.') && !var.key.startsWith('org.springframework')}"> 
     <input type="hidden" name="${var.key}" value="${var.value}" /> 
    </c:if> 
</c:forEach> 

Запрос атрибутов из пружинного каркаса и из Servlet действительно имеют префиксы, вам не нужно добавлять префикс атрибутов Вашего запроса.

Скорее вы можете игнорировать все те атрибуты, которые имеют префикс «org.springframework» или «javax.».

2

Для предотвращения головной боли с параметрами, добавленными контейнером Spring и Servlet, лучше использовать отдельную карту для значений пропусков в модели. Просто используйте @ModelAttribute и Spring будет создавать и добавлять его в модель автоматически:

@RequestMapping(value = "/method", method = RequestMethod.GET) 
public String myMethod(final Model model, @ModelAttribute("map") HashMap<String, Object> map) { 

    map.put("paramName1", "value1"); 
    map.put("paramName2", "value2"); 
    //...and so on 
} 

Теперь вы можете перебирать эту карту в JSP:

<c:forEach items="${map.keySet()}" var="key"> 
    <input type="hidden" name="${key}" value="${map[key]}"/> 
</c:forEach> 

Также вы можете получить доступ к каждому элементу карты следующим способом:

<c:out value="${map.paramName1}"/> 
<c:out value="${map.paramName2}"/> 
... 

Если вам не нужно какой-либо параметр, чтобы быть итерацией, добавьте его в исходный ModelMap istead отдельной карты.