javax.el.PropertyNotFoundException: 属性 [id] 未找到

javax.el.PropertyNotFoundException: Property [id] not found

我使用 Spring 引导项目,在 运行 应用

时出现以下错误
2017-10-03 22:10:36.726 ERROR 978 --- [nio-8081-exec-4] o.s.boot.web.support.ErrorPageFilter     : Forwarding to error page from request [/users] due to exception [An exception occurred processing JSP page [/WEB-INF/jsp/list.jsp] at line [44]

41: 
42:         <tbody>
43:         <c:forEach var="user" items="{users}">
44:             <tr><c:out value="${user.id}"/></tr>
45:             <tr><c:out value="${user.name}"/></tr>
46:             <tr><c:out value="${user.email}"/></tr>
47:         </c:forEach>

.........

.........
Caused by: javax.el.PropertyNotFoundException: Property [id] not found on type [java.lang.String]

用户class我有,

@Entity
public class User {

    // form:hidden - hidden value
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    // form:input - textbox
    @Column(name = "name", columnDefinition = "VARCHAR(30)", nullable = false)
    String name;

    // form:input - textbox
    @Column(name = "email", columnDefinition = "VARCHAR(50)", nullable = false)
    String email;

    // form:input - password
    @Column(name = "password", columnDefinition = "VARCHAR(20)", nullable = false)
    String password;

    // form:textarea - textarea
    @Column(name = "address", columnDefinition = "VARCHAR(255)")
    String address;

    // form:input - password
    @Transient
    String confirmPassword;

    // form:checkbox - single checkbox
    @Column(name = "newsletter")
    boolean newsletter;

    // form:radiobutton - radio button
    @Column(name = "sex", columnDefinition = "VARCHAR(1)")
    String sex;

    // form:radiobuttons - radio button
    @Column(name = "number")
    Integer number;

    // form:select - form:option - dropdown - single select
    @Column(name = "country", columnDefinition = "VARCHAR(10)")
    String country;

    // form:checkboxes - multiple checkboxes
    @ElementCollection
//    @Column(name = "framework", columnDefinition = "VARCHAR(500)")
    List<String> framework;

    // form:select - multiple=true - dropdown - multiple select
    @ElementCollection
//    @Column(name = "skill", columnDefinition = "VARCHAR(500)")
    List<String> skill;
}

提供了用户控制器class,

@Controller
public class UserController {

    private final Logger logger = LoggerFactory.getLogger(UserController.class);

    @Autowired
    private UserService userService;


    private static List<User> populateDefaultUserValues() {

        List<User> users = new ArrayList<>();

        User user = new User();
        user.setName("Ella");
        user.setEmail("xyz@gmail.com");
        user.setPassword("df32d343H");
        user.setFramework(Arrays.asList("Spring MVC, GWT".split("\s*,\s*")));
        users.add(user);


        user = new User();
        user.setName("Alex");
        user.setEmail("alex@hotmail.com");
        user.setPassword("12HH2d343H");
        user.setFramework(Arrays.asList("Spring MVC, GWT".split("\s*,\s*")));
        users.add(user);


        user = new User();
        user.setName("KKomanna");
        user.setEmail("romanna@hotmail.com");
        user.setPassword("Rommann343");
        user.setFramework(Arrays.asList("Spring MVC, GWT".split("\s*,\s*")));
        users.add(user);

        return users;
    }

    @GetMapping(value = "/")
    public String index() {
        return "redirect:/users";
    }

    @GetMapping(value = "/users")
    public String showAllUsers(Model model) {

        List<User> users = populateDefaultUserValues();

        users.forEach(user -> {
            userService.save(user);
        });

//        System.out.println("/n/n/n/n" + (userService.findAll()).stream().map(Object::toString)
//                .collect(Collectors.joining(", ")) + "/n/n/n/n");

        model.addAttribute("users", userService.findAll());
        return "list";
    }
}

我感觉 userService.findAll() return 是 List<String> 而不是 List<User>。一些实验,我碰巧知道 <c:out value="${users}"/> 将 return 一个包含 3 个元素的数组(我猜是姓名、电子邮件和密码)

我还计划访问框架值,例如

               `<td><c:forEach var="framework" items="${user.framework}" varStatus="loop">
                    ${framework}
                    <c:if test="${not loop.last}">,</c:if>
                    </c:forEach></td>
                <td>`

该应用程序在 MySQL 数据库中创建了 3 个表,即 useruser_frameworkuser_skill,并具有以下值,

并且,

我想用代码

填充 JSP
<c:forEach var="user" items="${users}">
                <tr>
                    <td>
                        ${user.id}
                    </td>
                    <td>${user.name}</td>
                    <td>${user.email}</td>
                    <td><c:forEach var="framework" items="${user.framework}" varStatus="loop">
                        ${framework}
                        <c:if test="${not loop.last}">,</c:if>
                        </c:forEach></td>
                    <td>
                   </tr>
            </c:forEach>

提供service目录的接口和实现,

public interface UserService {

    List<User> findAll();

    User findById(Long idx);

    void save(User user);

    void delete(Long idx);
}

实现在这里,

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public List<User> findAll() {
        return (List)userRepository.findAll();
    }

    @Override
    public User findById(Long idx) {
        return userRepository.findOne(idx);
    }

    @Override
    public void save(User user) {
        userRepository.save(user);
    }

    @Override
    public void delete(Long idx) {
        userRepository.delete(idx);
    }
}

如何解决错误并正确填充 JSP?

简而言之,由于注意力不集中,我犯了一个愚蠢的错误。要循环来自 Spring 控制器的列表,您需要先放置一个 $ 符号,然后循环遍历它。代码示例是

          <c:forEach var="user" items="${users}">
                <tr>
                    <td>
                        ${user.id}
                    </td>
                    <td>${user.name}</td>
                    <td>${user.email}</td>
                    <td><c:forEach var="framework" items="${user.framework}" varStatus="loop">
                        ${framework}
                        <c:if test="${not loop.last}">,</c:if>
                        </c:forEach></td>
                    <td>
                   </tr>
            </c:forEach>