首页 > 解决方案 > 访问链接到控制器类的页面时出现 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;
    }

}

标签: springspring-bootspring-mvc

解决方案


@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 实例。因此,使用不同的实例,就会出现上述问题。


推荐阅读