无法在 JSP 中获取模型属性的大小
Can't get the size of a model attribute in JSP
这是我使用 jsp 的第一个项目,我正在尝试构建一个 table,其中每一行看起来有点像这样
Here is a line of the table
最后一栏(点赞)目前只有一个按钮,但我想在旁边显示点赞数。
这是我的问题。当我尝试使用 jsp 函数长度 ${fn:length(mes.likes)}
我得到以下异常
org.apache.jasper.JasperException: javax.el.ELException: Problems calling function [fn:length]
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:606)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:482)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:170)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
我从 HomeController
加载模型中的所有消息
@Controller
public class HomeController {
@Autowired
IMessageService messageService;
@GetMapping("/homepage")
public String index(Model model) {
List<MessageEntity> messages = messageService.getAll();
model.addAttribute("allMessages", messages);
return "index";
}
}
这里是 MessageEntity class
public class MessageEntity{
private int Id;
private String title;
private String content;
private Date createdAt;
private User createdBy;
private List<LikeEntity> likes;
}
最后,这是我在 index.jsp 文件中显示信息的 table。
<table id="panneau">
<thead class="bg-dark text-light">
<tr>
<th>Message</th>
<th>Emetteur</th>
<th>Date/heure</th>
<th>Likes</th>
</tr>
</thead>
<tbody class="text-black">
<c:forEach var="mes" items="${allMessages}">
<tr id="message${mes.id}">
<td>
<div><b>${mes.title}</b></div>
<div>${mes.content}</div>
</td>
<td>
<c:choose>
<c:when test="${mes.anonymous}">
anonyme
</c:when>
<c:otherwise>
${mes.createdBy.firstName} ${mes.createdBy.lastName}
</c:otherwise>
</c:choose>
</td>
<td>
${mes.createdAt}
</td>
<td>
<div>${fn:length(mes.likes)}</div>
<div><button class="btn btn-dark" id="like${mes.id}"><i class="far fa-thumbs-up fa-2x"></i></button></div>
</td>
</tr>
</c:forEach>
</tbody>
</table>
当我删除 ${fn:length(mes.likes)}
时,一切正常,但我需要一种方法来获取此信息。
我看过其他类似的问题,但 none 似乎解决了我的问题。
顺便说一下,我在文件的开头确实有 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
编辑
这里是likeEntityclass
import javax.persistence.*;
import java.util.Objects;
/**
* Created by owner on 18-05-07.
*/
@Entity
@Table(name = "likes", schema = "heroku_9efd0238a94d992")
public class LikeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "like_id", nullable = false)
private int id;
@Basic
@Column(name = "is_dislike", nullable = true)
private Boolean isDislike;
@ManyToOne(cascade = {
CascadeType.MERGE,
CascadeType.PERSIST,
CascadeType.DETACH,
CascadeType.REFRESH,
})
@JoinColumn(name = "liked_by")
private UserEntity likedBy;
@ManyToOne(cascade = {
CascadeType.MERGE,
CascadeType.PERSIST,
CascadeType.DETACH,
CascadeType.REFRESH,
})
@JoinColumn(name = "liked_message")
private MessageEntity likedMessage;
public LikeEntity() {
this.setDislike(false);
}
}
Disclamer:这是一个解决方法,不是真正的解决方案
我仍然不知道为什么 likes 不能延迟加载,但是将 fetchtype 从延迟加载改为急切似乎已经成功了......
我知道这个解决方案不是最优的。就我而言,此解决方法是合适的,因为它只是一个学校项目,所以我永远不会在一条消息中获得数千个赞。
但是,如果您处理大量数据,我认为此解决方案不合适。
这是我使用 jsp 的第一个项目,我正在尝试构建一个 table,其中每一行看起来有点像这样
Here is a line of the table
最后一栏(点赞)目前只有一个按钮,但我想在旁边显示点赞数。
这是我的问题。当我尝试使用 jsp 函数长度 ${fn:length(mes.likes)}
我得到以下异常
org.apache.jasper.JasperException: javax.el.ELException: Problems calling function [fn:length]
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:606)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:482)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:386)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:330)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:170)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:314)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:1325)
org.springframework.web.servlet.DispatcherServlet.processDispatchResult(DispatcherServlet.java:1069)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1008)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870)
javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:320)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:127)
org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:91)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:119)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:137)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:111)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:170)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:63)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilterInternal(BasicAuthenticationFilter.java:158)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:200)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:100)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:66)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:105)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:56)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:334)
org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:215)
org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:178)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:357)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:270)
我从 HomeController
加载模型中的所有消息@Controller
public class HomeController {
@Autowired
IMessageService messageService;
@GetMapping("/homepage")
public String index(Model model) {
List<MessageEntity> messages = messageService.getAll();
model.addAttribute("allMessages", messages);
return "index";
}
}
这里是 MessageEntity class
public class MessageEntity{
private int Id;
private String title;
private String content;
private Date createdAt;
private User createdBy;
private List<LikeEntity> likes;
}
最后,这是我在 index.jsp 文件中显示信息的 table。
<table id="panneau">
<thead class="bg-dark text-light">
<tr>
<th>Message</th>
<th>Emetteur</th>
<th>Date/heure</th>
<th>Likes</th>
</tr>
</thead>
<tbody class="text-black">
<c:forEach var="mes" items="${allMessages}">
<tr id="message${mes.id}">
<td>
<div><b>${mes.title}</b></div>
<div>${mes.content}</div>
</td>
<td>
<c:choose>
<c:when test="${mes.anonymous}">
anonyme
</c:when>
<c:otherwise>
${mes.createdBy.firstName} ${mes.createdBy.lastName}
</c:otherwise>
</c:choose>
</td>
<td>
${mes.createdAt}
</td>
<td>
<div>${fn:length(mes.likes)}</div>
<div><button class="btn btn-dark" id="like${mes.id}"><i class="far fa-thumbs-up fa-2x"></i></button></div>
</td>
</tr>
</c:forEach>
</tbody>
</table>
当我删除 ${fn:length(mes.likes)}
时,一切正常,但我需要一种方法来获取此信息。
我看过其他类似的问题,但 none 似乎解决了我的问题。
顺便说一下,我在文件的开头确实有 <%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
编辑
这里是likeEntityclass
import javax.persistence.*;
import java.util.Objects;
/**
* Created by owner on 18-05-07.
*/
@Entity
@Table(name = "likes", schema = "heroku_9efd0238a94d992")
public class LikeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "like_id", nullable = false)
private int id;
@Basic
@Column(name = "is_dislike", nullable = true)
private Boolean isDislike;
@ManyToOne(cascade = {
CascadeType.MERGE,
CascadeType.PERSIST,
CascadeType.DETACH,
CascadeType.REFRESH,
})
@JoinColumn(name = "liked_by")
private UserEntity likedBy;
@ManyToOne(cascade = {
CascadeType.MERGE,
CascadeType.PERSIST,
CascadeType.DETACH,
CascadeType.REFRESH,
})
@JoinColumn(name = "liked_message")
private MessageEntity likedMessage;
public LikeEntity() {
this.setDislike(false);
}
}
Disclamer:这是一个解决方法,不是真正的解决方案
我仍然不知道为什么 likes 不能延迟加载,但是将 fetchtype 从延迟加载改为急切似乎已经成功了......
我知道这个解决方案不是最优的。就我而言,此解决方法是合适的,因为它只是一个学校项目,所以我永远不会在一条消息中获得数千个赞。
但是,如果您处理大量数据,我认为此解决方案不合适。