今天做毕业设计到分类功能的时分类列表分页时遇到了一个问题就是java.lang.NullPointerException: null,很困惑,一直没有找到解决问题的办法,在此记录一下。

1. 报错信息

首先来贴一下报错信息,信息如下:

java.lang.NullPointerException: null
	at com.sry.web.admin.TypeController.types(TypeController.java:28)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:197)
	at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:141)
	at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:106)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:894)
	at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:808)
	at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
	at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1060)
	at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:962)
	at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
	at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:898)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:626)
	at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:119)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:202)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
	at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:374)
	at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
	at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:888)
	at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1597)
	at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
	at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
	at java.lang.Thread.run(Thread.java:748)

2021-02-16 14:37:37.576  WARN 1820 --- [nio-8080-exec-8] .m.m.a.ExceptionHandlerExceptionResolver : Resolved [java.lang.NullPointerException]

2. Web层代码

@Controller
@RequestMapping("/admin")
public class TypeController {

    // 1.注入TypeService
    private TypeService typeService;

    // 2.分页列表的展示页面
    // 设置默认值,每页的条数、参数、排序(按照id倒序排序)等通过@PageableDefault注解来实现初始化页面属性
    @GetMapping("/types")
    public String types(@PageableDefault(size = 10, sort = {"id"}, direction = Sort.Direction.DESC) Pageable pageable, Model model) {
        /**
         * 将查询到的东西放到前端的页面展示模型
         * pageable是前端页面根据构造好的参数自动封装到Pageable这个对象中
         * 是SpringBoot里面封装好的自动实现分页的方法
         */
        model.addAttribute("page", typeService.listType(pageable));
        return "admin/types";
    }

    // 3.返回新增页面
    @GetMapping("/types/input")
    public String input() {
        return "admin/types-input";
    }
}

3. service层代码

3.1 service接口

public interface TypeService {

    // 新增接口saveType方法为保存,传递的是type的实体对象
    Type saveType(Type type);
    // 查询接口,根据Long类型的id来查询
    Type getType(Long id);
    // 分页查询,传递的是pageable对象
    Page<Type> listType(Pageable pageable);
    // 修改,传递的参数是根据id查找到实体对象,然后将对象根据新的内容加以修改并保存到数据库
    Type updateType(Long id, Type type);
    // 删除,根据主键删除并返回空
    void deleteType(Long id);

}

3.2 serviceImpl

@Service
public class TypeServiceImpl implements TypeService{

    // 2.注入Dao层的TypeRepository
    @Autowired
    private TypeRepository typeRepository;

    // 1.实现接口里面的方法
    // 3.实现具体的方法
    // 新增
    @Transactional
    @Override
    public Type saveType(Type type) {
        return typeRepository.save(type);
    }

    // 查询
    @Transactional
    @Override
    public Type getType(Long id) {
        // 根据id来查询单独的Type对象
        return typeRepository.findById(id).orElse(null);
    }

    // 分页查询
    @Transactional
    @Override
    public Page<Type> listType(Pageable pageable) {
        // 查询传递的是封装成Page类型的对象,返回Page<Type>类型的列表
        return typeRepository.findAll(pageable);
    }

    // 修改
    @Transactional
    @Override
    public Type updateType(Long id, Type type) {
        // 根据id查询对象
        Type t = typeRepository.findById(id).orElse(null);
        // 判断如果没有查询到抛出异常
        if (t == null) {
            throw new NotFoundException("不存在该类型...");
        }
        // 如果类型存在,将Type里面的东西复制到查询到的t这个对象上
        BeanUtils.copyProperties(type, t);
        // 因为t对象中有id,会出现更新的动作
        return typeRepository.save(t);
    }

    // 删除
    @Transactional
    @Override
    public void deleteType(Long id) {
        typeRepository.deleteById(id);
    }
}

4. Dao层代码

这里暂时就实现是这样设计的,后面会继续写博客分类新增、修改、删除等功能,后面还会加以补充。

public interface TypeRepository extends JpaRepository<Type, Long> {
}

5. 页面处理

<!-- 中间内容 -->
<div class="c-padded-tb-big c-container-small">
	<div class="ui container">
		<table class="ui celled table">
			<thead>
				<tr>
					<th></th>
					<th>名称</th>
					<th>操作</th>
				</tr>
			</thead>
			<tbody>
				<!--each循环,type为循环对象,从page里面的content数据列表中获取type对象-->
				<!--iterStat可以用来实现计数的功能,实现分页按序号计数,使得每页的序号都从1开始-->
				<tr th:each="type, iterStat : ${page.content}">
					<td th:text="${iterStat.count}">1</td>
					<!--把对应属性中的值取出来填充到表格中相应的位置-->
					<td th:text="${type.name}">Java Web开发共享单车地图服务平台项目日常记录</td>
					<td>
						<!--此时编辑的方法还没有实现,可以先来预定义-->
						<!--返回一个能够查询到之前保存数据的页面,id=${type.id}可以替换掉{id},并访问到/admin/types/{id}的一个路径-->
						<a href="#" th:href="@{/admin/types/{id}/input(id=${type.id})}" class="ui mini blue basic button">编辑</a>
						<a href="#" th:href="@{/admin/types/{id}/delete(id=${type.id})}" class="ui mini red basic button">删除</a>
					</td>
				</tr>
			</tbody>
			<tfoot>
				<tr>
					<th colspan="6">
						<div class="ui mini  pagination menu">								
							<a class="icon item">
								<i class="left chevron icon"></i>
							</a>
							<a th:href="@{/admin/types(page=${page.number}-1)}" class="item">上一页</a>
							<a th:href="@{/admin/types(page=${page.number}+1)}" class="item">下一页</a>
							<a class="icon item">
								<i class="right chevron icon"></i>
							</a>
						</div>
						<a href="#" th:href="@{/admin/types/input}" class="ui mini right floated pink basic button">新增</a>
					</th>
				</tr>
			</tfoot>
		</table>
	</div>
</div>

6. 解决方法

仔细查看之后发现是在引入TypeService时没有引入注解@Autowired,如下如所示

在上面引入即可

找了一天也没有找到问题,结果就失败在这小小的一行注解上。

希望对你们有所帮助啦,如果你们也是这个问题的话可以仔细看看是不是注解没有添加上,当然不是只有这一个地方有注解,细心一点把其他的需要注解的地方都检查一遍没准就成功了呢。

更多推荐

springboot项目之java.lang.NullPointerException: null问题