如何在JSP中通过字段名获取Spring MVC模型属性值?
动态列展示解决方案:JSP中按字段名获取实体属性值
问题回顾
你现在的场景是:做一个可配置列的国家信息表格,后台通过Spring MVC传了两个模型属性——selColumns(用户选中的列键列表)和countryDetails(CountryDetails实体类的列表),但JSP里用${item.det}这种方式无法正确获取对应字段的值,因为EL表达式会自动去匹配实体类的getDet()方法,而不是直接按字段名取值。
下面给你几种实用的解决办法,按复杂度和推荐度排序:
方法1:后台转Map(最推荐,简单直接)
把实体类转换成Map<String, Object>传给前端,这样EL可以直接通过键名取值,完全避开反射的麻烦。
后台修改代码
// 假设原来的国家列表是List<CountryDetails> countryList List<Map<String, Object>> countryMapList = new ArrayList<>(); for (CountryDetails country : countryList) { Map<String, Object> map = new HashMap<>(); // 把实体类的每个字段对应放到Map里,键名和selColumns的列键完全一致 map.put("country", country.getCountry()); map.put("population", country.getPopulation()); map.put("CapitalCity", country.getCapitalCity()); map.put("Aria", country.getAria()); countryMapList.add(map); } // 替换原来的countryDetails为Map列表 model.addAttribute("countryDetails", countryMapList);
前端JSP代码
<table border="1"> <thead> <tr> <c:forEach var="colKey" items="${selColumns}"> <!-- 这里如果selColumns是键和列名的映射(比如Map),就用${colKey.value},如果只是键列表就直接${colKey} --> <th>${colKey}</th> </c:forEach> </tr> </thead> <tbody> <c:forEach var="country" items="${countryDetails}"> <tr> <c:forEach var="colKey" items="${selColumns}"> <!-- 直接用Map的键取值,完美匹配配置列 --> <td>${country[colKey]}</td> </c:forEach> </tr> </c:forEach> </tbody> </table>
方法2:自定义EL函数(用反射动态取值)
如果不想修改后台逻辑,可以写一个反射工具类,做成EL函数,在JSP里直接调用获取属性值。
步骤1:写反射工具类
package com.yourcompany.utils; import java.lang.reflect.Method; public class ReflectionUtils { public static Object getPropertyValue(Object obj, String propertyName) throws Exception { // 拼接getter方法名:比如country -> getCountry() String getterName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1); Method getter = obj.getClass().getMethod(getterName); return getter.invoke(obj); } }
步骤2:定义EL函数(创建tld文件)
在WEB-INF下新建utils.tld:
<?xml version="1.0" encoding="UTF-8"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd" version="2.0"> <tlib-version>1.0</tlib-version> <short-name>utils</short-name> <uri>http://yourcompany.com/jsp/utils</uri> <function> <name>getProperty</name> <function-class>com.yourcompany.utils.ReflectionUtils</function-class> <function-signature>java.lang.Object getPropertyValue(java.lang.Object, java.lang.String)</function-signature> </function> </taglib>
步骤3:JSP中使用EL函数
<%@ taglib prefix="utils" uri="http://yourcompany.com/jsp/utils" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <table border="1"> <thead> <tr> <c:forEach var="colKey" items="${selColumns}"> <th>${colKey}</th> </c:forEach> </tr> </thead> <tbody> <c:forEach var="country" items="${countryDetails}"> <tr> <c:forEach var="colKey" items="${selColumns}"> <!-- 调用自定义EL函数,传入实体对象和字段名 --> <td>${utils:getProperty(country, colKey)}</td> </c:forEach> </tr> </c:forEach> </tbody> </table>
方法3:用Spring BeanWrapper(更健壮的反射方式)
如果你的项目用了Spring,可以用BeanWrapper来处理属性取值,它比自己写反射更安全,能自动处理字段名和getter的匹配、类型转换等问题。
工具类修改
package com.yourcompany.utils; import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; public class ReflectionUtils { public static Object getPropertyValue(Object obj, String propertyName) { BeanWrapper wrapper = new BeanWrapperImpl(obj); return wrapper.getPropertyValue(propertyName); } }
后面的EL函数定义和JSP用法和方法2完全一样,只是工具类的实现换了Spring的方式。
内容的提问来源于stack exchange,提问作者user3305063
相关产品推荐
相关产品推荐

