spring - 访问链接到控制器类的页面时出现 java.lang.NullPointerException 错误
问题描述
我正在运行一个带有注释为@controller、@service、@component 的类的spring mvc 应用程序,并且使用了视图层百里香。但是,在导航到路径 localhost:8080/owners 时,不会显示任何所有者数据。看起来即使数据已保存在所有者对象中,但 ownerservicemap 无缘无故为空。
下面是错误
Owner data is loaded
2019-06-26 12:39:47.237 INFO 5776 --- [ restartedMain]
.ConditionEvaluationDeltaLoggingListener : Condition evaluation
unchanged
2019-06-26 12:39:50.475 INFO 5776 --- [nio-8080-exec-1]
o.a.c.c.C.[Tomcat-1].[localhost].[/] : Initializing Spring
DispatcherServlet 'dispatcherServlet'
2019-06-26 12:39:50.475 INFO 5776 --- [nio-8080-exec-1]
o.s.web.servlet.DispatcherServlet : Initializing Servlet
'dispatcherServlet'
2019-06-26 12:39:50.483 INFO 5776 --- [nio-8080-exec-1]
o.s.web.servlet.DispatcherServlet : Completed initialization in
8 ms
2019-06-26 12:39:50.507 ERROR 5776 --- [nio-8080-exec-1]
o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for
servlet [dispatcherServlet] in context with path [] threw exception
[Request processing failed; nested exception is
java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
at com.example.Project.controllers.OwnerController.listOwners(OwnerController.java:33)
~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_211]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
~[na:1.8.0_211]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
~[na:1.8.0_211]
at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_211]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:190)
DataLoader 类加载数据
@Component public class DataLoader implements CommandLineRunner{
private final OwnerService ownerService;
public DataLoader()
{
ownerService=new OwnerServiceMap();
}
@Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
Owner owner1=new Owner();
owner1.setId(1L);
owner1.setFirstName("ally");
owner1.setLastName("nilson");
Owner sa1=ownerService.save(owner1);
}}
下面是所有者控制器类
@RequestMapping("/owners") @Controller public class OwnerController {
private OwnerService ownerservice;
@Autowired
public OwnerController(OwnerService ownerservice)
{
this.ownerservice=ownerservice;
}
@RequestMapping({"","/","/index","/index.html"})
public String listOwners(Model model)
{
model.addAttribute("owner",ownerservice.findAll());// System.out.println(ownerservice.findById(1L).getLastName());
return "owner/index";
}}
所有者服务接口
public interface OwnerService extends CrudService<Owner, Long>{
Owner findByLastName(String lastname);}
AbstractmapService 类
public abstract class AbstractMapService<T,ID> {
protected Map<ID,T> map=new HashMap<>();
Set<T> findAll()
{
return new HashSet<>(map.values());
}
T findById(ID id)
{
return map.get(id);
}
T save(ID id,T object)
{
map.put(id, object);
return object;
}
void deleteById(ID id)
{
map.remove(id);
}
void delete(T object)
{
map.entrySet().removeIf(entry->entry.getValue().equals(object));
}}
OwnerServiceMap 类
@Service public class OwnerServiceMap extends AbstractMapService<Owner,Long>implements OwnerService{
@Override
public Set<Owner> findAll() {
// TODO Auto-generated method stub
return super.findAll();
}
@Override
public Owner findById(Long id) {
// TODO Auto-generated method stub
return super.findById(id);
}
@Override
public Owner save(Owner object) {
// TODO Auto-generated method stub
return super.save(object.getId(),object);
}
@Override
public void delete(Owner object) {
// TODO Auto-generated method stub
super.delete(object);
}
@Override
public void deleteById(Long id) {
// TODO Auto-generated method stub
super.deleteById(id);
}
@Override
public Owner findByLastName(String lastname) {
// TODO Auto-generated method stub
return null;
}
}
解决方案
@Service
public class OwnerServiceMap extends AbstractMapService<Owner,Long> implements OwnerService{ ... // }
要自动装配,您必须向 bean 注册。
编辑1
您确实保存了另一个服务的地图。
@Component public class DataLoader implements CommandLineRunner{
private final OwnerService ownerService;
public DataLoader()
{
ownerService=new OwnerServiceMap();
}
// ...
和这里,
@RequestMapping("/owners") @Controller public class OwnerController {
private OwnerService ownerservice;
@Autowired
public OwnerController(OwnerService ownerservice)
{
this.ownerservice=ownerservice;
}
请检查这个。
编辑2
如果您将 Object 注册到 bean,则容器通过单例对象拥有该对象。然后,使用 @Autowired 从容器中获取单例对象。
注意:与 GOF 的单例不同。
总而言之,您使用 new 关键字 likeownerService=new OwnerServiceMap();
是创建一个新实例,而不是使用您分配给容器的 bean 实例。因此,使用不同的实例,就会出现上述问题。
推荐阅读
- android - Xamarin Android:从 Java 到 C# 的等效代码是什么:resource.getConfiguration().getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
- python - 独立脚本中的交互式数据帧散点图(没有 jupyter)
- r - 根据来自不同列的另一行更改行的值
- rust - 有没有办法将多个派生别名为单个派生?
- node.js - 使用 javascript 的 MongoDB 动态查询,静态工作,而不是变量
- php - 从侧面修剪空白并允许单词之间有空格
- asp.net-core - 如何将 ID 从 SelectList 保存到另一个表的字段?
- java - 单击时在 JavaFX 中填充组合框
- jestjs - 为什么 Angular 规范文件中的 ApolloTestingModule 会开玩笑抛出:“无法读取未定义的属性‘使用’?
- android - 如何制作这种类型的可展开视图