我有Spring项目,现在我想添加几个JSF(Primefaces)xhtml页面,但是当我尝试从现有服务获取数据时,在@PostConstruct方法上的@ManagedBean中出现空指针异常?
您知道如何正确地将AuctionViewService导入到我的@ManagedBean吗?我认为这是问题所在,但我不知道如何解决:)
在Java类下面,有带空指针的stacktrace(我也在SalesBean.java中用NPE标记行)
这是我的xhtml页面:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/bootstrap.min.css"></link>
<link rel="stylesheet" href="${pageContext.request.contextPath}/css/main.css"></link>
<script src="${pageContext.request.contextPath}/js/jquery-3.4.1.min.js" type=""></script>
<script src="${pageContext.request.contextPath}/js/bootstrap.min.js" type=""></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/js/common/main.js"></script>
<title>Sales</title>
</h:head>
<h:body>
<div id="wrapper">
<div id="navigationMenuPlaceholder"></div>
<!-- Page Content -->
<div id="page-content-wrapper">
<div class="container-fluid">
<div class="row">
<div class="col-lg-12">
<p:panelGrid columns="2">
<h:outputText value="#{SalesBean.firstName}"/>
<h:outputText value="#{SalesBean.lastName}" />
</p:panelGrid>
<p:dataTable var="property" value="#{SalesBean.userProperty}">
<p:column headerText="PropertyId">
<h:outputText value="#{property.propertyId}" />
</p:column>
<p:column headerText="UserId">
<h:outputText value="#{property.userId}" />
</p:column>
<p:column headerText="Street">
<h:outputText value="#{property.street}" />
</p:column>
<p:column headerText="House no">
<h:outputText value="#{property.homeNumber}" />
</p:column>
<p:column headerText="Local no">
<h:outputText value="#{property.localNumber}" />
</p:column>
<p:column headerText="Post code">
<h:outputText value="#{property.postCode}" />
</p:column>
<p:column headerText="City">
<h:outputText value="#{property.city}" />
</p:column>
<p:column headerText="Price">
<h:outputText value="#{property.price}" />
</p:column>
<p:column headerText="Size">
<h:outputText value="#{property.size}" />
</p:column>
</p:dataTable>
</div>
</div>
</div>
</div>
<div id="footerPlaceholder">
</div>
<!-- /#page-content-wrapper -->
</div>
</h:body>
</html>
SalesBean:
package application.beans;
import application.model.views.AuctionView;
import application.service.AuctionViewService;
import lombok.Getter;
import lombok.Setter;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import java.util.ArrayList;
import java.util.List;
@Setter
@Getter
@ViewScoped
@ManagedBean(name="SalesBean")
public class SalesBean {
@ManagedProperty("#{auctionViewService}")
private AuctionViewService auctionViewService;
//private String userName = SecurityContextHolder.getContext().getAuthentication().getName();
private String userName = "[email protected]";
private String firstName = "first";
private String lastName = "last";
private List<AuctionView> userProperty = new ArrayList<>();
@PostConstruct
public void init() { userProperty = auctionViewService.findByEmail(userName); //NULL POINTER EXCEPTION in this line
}
}
AuctionViewServiceImpl:
package application.service;
import application.dao.*;
import application.model.views.AuctionView;
import org.apache.log4j.Logger;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import java.util.List;
@Service("auctionViewService")
public class AuctionViewServiceImpl implements AuctionViewService {
final static Logger LOGGER = Logger.getLogger(AuctionViewServiceImpl.class.getName());
private final AuctionViewDAO auctionViewDAO;
public AuctionViewServiceImpl(AuctionViewDAO auctionViewDAO) {
this.auctionViewDAO = auctionViewDAO;
}
@Override
public List<AuctionView> findAll() {
return auctionViewDAO.findAll();
}
@Override
public ResponseEntity<Object> findByType(String propertyType) {
return new ResponseEntity<>(auctionViewDAO.findByType(propertyType), HttpStatus.OK);
}
@Override
public List<AuctionView> findByEmail(String email) {
return auctionViewDAO.findByEmail(email);
}
}
faces-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config 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-facesconfig_2_1.xsd"
version="2.1">
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
</faces-config>
web.xml
<web-app version="2.4"
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-app_2_4.xsd">
<display-name>khn</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:/applicationContext.xml</param-value>
</context-param>
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
stacktrace:https://pastebin.com/iaBHUupQ如果需要,我可以附加更多文件和整个项目结构,但是问题是将AuctionViewService导入SalesBean,或者可能是混合JSF和Spring注释
好吧,我将@ManagedBean批注更改为@Component,将AuctionViewService与@Autowire链接起来,它对我有用:),但是如何解释这种情况?
package application.beans;
import application.model.views.AuctionView;
import application.service.AuctionViewService;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
@Setter
@Getter
@ViewScoped
@Component
//@ManagedBean(name="SalesBean")
public class SalesBean implements Serializable {
@Autowired
private AuctionViewService auctionViewService;
//private String userName = SecurityContextHolder.getContext().getAuthentication().getName();
private String userName = "[email protected]";
private String firstName = "first";
private String lastName = "last";
private List<AuctionView> userProperty = new ArrayList<>();
@PostConstruct
public void init() { userProperty = auctionViewService.findByEmail(userName);
}
}