할수있다.
20
2020-11-17 18:17:10
2
562

[스프링] 게시판 페이징 오류 도와주세요ㅠㅠ


[오류페이지]

HTTP 상태 500 – 내부 서버 오류


타입 예외 보고

메시지 Request processing failed; nested exception is java.lang.NullPointerException

설명 서버가, 해당 요청을 충족시키지 못하게 하는 예기치 않은 조건을 맞닥뜨렸습니다.

예외

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:894)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

근본 원인 (root cause)

java.lang.NullPointerException
	com.book.model.PageMakerVO.calcData(PageMakerVO.java:22)
	com.book.model.PageMakerVO.setTotalCount(PageMakerVO.java:71)
	com.book.controller.NoticeController.getList(NoticeController.java:42)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	java.base/java.lang.reflect.Method.invoke(Method.java:566)
	org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:213)
	org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:126)
	org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:96)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:617)
	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:578)
	org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:80)
	org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:923)
	org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:852)
	org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:882)
	org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:778)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
	javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
	org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
	org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
	org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)

비고 근본 원인(root cause)의 풀 스택 트레이스를, 서버 로그들에서 확인할 수 있습니다.


Apache Tomcat/9.0.22


package com.book.controller;

import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.book.model.NoticeVO;
import com.book.model.PageMakerVO;
import com.book.model.PagingVO;
import com.book.model.SearchPagingVO;
import com.book.service.NoticeService;

@Controller
@RequestMapping("/notice/*")
public class NoticeController {
	
	@Inject
	NoticeService service;
	
	//공지사항 목록
	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public void getList(@ModelAttribute("pagingVO") PagingVO pagingVO, Model model) throws Exception {
	
		System.out.println("get NoticeList");

	   List<NoticeVO> list =null;
	   System.out.println("get NoticeList2");
	   list = service.list(pagingVO);
	   System.out.println("get NoticeList3");
	   
		// 게시글 총 수
		PageMakerVO pageMakerVO = new PageMakerVO();
		System.out.println("get NoticeList4");
		pageMakerVO.setTotalCount(service.count());
		System.out.println("get NoticeList5");
		model.addAttribute("pageMakerVO", pageMakerVO);
		System.out.println("get NoticeList6");
	   
	   model.addAttribute("list",list);
	}
	
	//공지사항 조회
	@RequestMapping(value = "/view", method = RequestMethod.GET)
	public void getView(@RequestParam("notice_id") int notice_id, Model model) throws Exception{
	   NoticeVO vo = service.view(notice_id);
	 
	   model.addAttribute("view", vo);
	}
	
	//공지사항 작성 (GET)
	@RequestMapping(value = "/write", method = RequestMethod.GET)
	public void getWirte() throws Exception{
	    
	}
	
	//공지사항 작성 (POST)
	@RequestMapping(value = "/write", method =RequestMethod.POST)
	public String posttWirte(NoticeVO vo) throws Exception{
	   service.write(vo);
	     
	   return "redirect:/notice/list";
	}
	   
	//공지사항 수정 (GET)
	@RequestMapping(value = "/modify", method = RequestMethod.GET)
	public void getModify(@RequestParam("notice_id") int notice_id, Model model) throws Exception {
	   NoticeVO vo = service.view(notice_id);
	     
	   model.addAttribute("view", vo);
	}
	  
	//공지사항 수정 (POST)
	@RequestMapping(value = "/modify", method =  RequestMethod.POST)
	public String postModify(NoticeVO vo) throws Exception{
	   service.modify(vo);  //수정
	     
	   return "redirect:/notice/view?notice_id=" + vo.getNotice_id(); 
	}
	  
	//공지사항 삭제
	@RequestMapping(value = "/delete", method = RequestMethod.GET)
	public String getDelete(@RequestParam("notice_id") int notice_id) throws Exception{
	   service.delete(notice_id);
	     
	   return "redirect:/notice/list";
	}
	
	
}
package com.book.dao;

import java.util.List;

import com.book.model.NoticeVO;
import com.book.model.PagingVO;

public interface NoticeDAO {
	
	//공지사항 목록
	public List<NoticeVO> list(PagingVO PagingVO) throws Exception;
	
	//공지사항 조회
	public NoticeVO view(int notice_id) throws Exception;

	//공지사항 작성
	public void write(NoticeVO vo) throws Exception;
	   
	//공지사항 수정
	public void modify(NoticeVO vo) throws Exception;
	   
	//공지사항 삭제
	public void delete(int notice_id) throws Exception;
	
	//공지사항 총 개수 count
	public int count() throws Exception;
 

}
package com.book.dao;
package com.book.dao;

import java.util.List;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;
import org.springframework.stereotype.Repository;

import com.book.model.NoticeVO;
import com.book.model.PagingVO;

@Repository
public class NoticeDAOImpl implements NoticeDAO {
	
	@Inject
	private SqlSession sql;
	
	private static String namespace="com.book.mappers.noticeMapper";

	//공지사항 목록
	@Override
	public List<NoticeVO> list(PagingVO PagingVO) throws Exception {
		return sql.selectList(namespace+".list");
	}


	//공지사항 조회
	@Override
	public NoticeVO view(int notice_id) throws Exception {
		return sql.selectOne(namespace+".view", notice_id);
	}
	
	//공지사항 작성
	@Override
	public void write(NoticeVO vo) throws Exception {
		sql.insert(namespace+".write", vo);
	}
	
	//공지사항 수정
	@Override
	public void modify(NoticeVO vo) throws Exception {
		sql.update(namespace+".modify", vo);
	}

	//공지사항 삭제
	@Override
	public void delete(int notice_id) throws Exception {
		sql.delete(namespace + ".delete", notice_id); 
	}
	
	//공지사항 총 개수
	@Override
	public int count() throws Exception {
		// TODO Auto-generated method stub
		return sql.selectOne(namespace + ".count");
	}






	


	package com.book.service;

import java.util.List;

import com.book.model.NoticeVO;
import com.book.model.PagingVO;

public interface NoticeService {
	
	//공지사항 목록
	public List<NoticeVO> list(PagingVO PagingVO) throws Exception;

	//공지사항 작성
	public void write(NoticeVO vo) throws Exception;
	   
	//공지사항 조회
	public NoticeVO view(int notice_id) throws Exception;
	
	//공지사항 수정
	public void modify(NoticeVO vo) throws Exception;
	   
	//공지사항 삭제
	public void delete(int notice_id) throws Exception;

	
	//공지사항 총 개수
	public int count() throws Exception;
	

}

}
package com.book.service;

import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import com.book.dao.NoticeDAO;
import com.book.model.NoticeVO;
import com.book.model.PagingVO;

@Service
public class NoticeServiceImpl implements NoticeService {
	
	@Inject
	private NoticeDAO dao;

	//공지사항 목록
	@Override
	public List<NoticeVO> list(PagingVO PagingVO) throws Exception {
		return dao.list(PagingVO);
	}



	
	//공지사항 작성
	@Override
	public void write(NoticeVO vo) throws Exception {
		dao.write(vo);      
	}

	
	//공지사항 수정
	@Override
	public void modify(NoticeVO vo) throws Exception {
		dao.modify(vo);
	}

	//공지사항 삭제
	@Override
	public void delete(int notice_id) throws Exception {
		dao.delete(notice_id);
	}

	
	//공지사항 조회
	@Override
	public NoticeVO view(int notice_id) throws Exception {
		
		//하나의 데이터를 읽어서 리턴
		return dao.view(notice_id);
	}
	
	//공지사항 총 개수
	@Override
	public int count() throws Exception {
		return dao.count();
	}




	
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  
<mapper namespace="com.book.mappers.noticeMapper">

	<!-- 공지사항 목록, 페이징 -->
	<select id="list" resultType="com.book.model.NoticeVO" parameterType="com.book.model.PagingVO">
		SELECT *
		FROM ( SELECT notice_id, notice_title,notice_content, notice_date,notice_click,user_id,  row_number() over(order by notice_id desc) as rNum
       		   FROM boddarinotice
       		 
       		   ) mb
		WHERE rNum BETWEEN #{rowStart, jdbcType=VARCHAR} AND #{rowEnd, jdbcType=VARCHAR}
		ORDER BY notice_id desc
	</select>
	
	
	<!-- 공지사항  게시글 총 개수 -->
	<select id="count" resultType="int">
	<![CDATA[
			SELECT count(notice_id)
			FROM boddarinotice
			WHERE notice_id > 0
		]]>
	
	</select>

	<!-- 공지사항 작성-->
	<insert id="write" parameterType="com.book.model.NoticeVO">
		insert into boddarinotice
		(notice_id,notice_title,notice_content,user_id)
		values(boddarinotice_seq.nextval, #{notice_title},#{notice_content},#{user_id})
	</insert>

	<!-- 공지사항 조회 (상세보기 글번호 해당 데이터 가져옴)-->
	<select id="view" parameterType="int" resultType="com.book.model.NoticeVO">
		select notice_id, notice_title, notice_content, notice_date, notice_click, user_id
		from boddarinotice
		where notice_id = #{notice_id}
	</select>

	<!-- 공지사항 수정 -->
	<update id="modify" parameterType="com.book.model.NoticeVO">
		update boddarinotice
		set
		notice_title = #{notice_title},
		notice_content = #{notice_content},
		user_id = #{user_id}
		where notice_id = #{notice_id}
	</update>

	
	<!-- 공지사항 삭제 -->
	<delete id="delete" parameterType="int"> 
		delete from boddarinotice
		where notice_id= #{notice_id}
	</delete>

 </mapper>






	//공지사항 조회
	@Override
	public NoticeVO view(int notice_id) throws Exception {
		return sql.selectOne(namespace+".view", notice_id);
	}
	
	//공지사항 작성
	@Override
	public void write(NoticeVO vo) throws Exception {
		sql.insert(namespace+".write", vo);
	}
	
	//공지사항 수정
	@Override
	public void modify(NoticeVO vo) throws Exception {
		sql.update(namespace+".modify", vo);
	}

	//공지사항 삭제
	@Override
	public void delete(int notice_id) throws Exception {
		sql.delete(namespace + ".delete", notice_id); 
	}
	
	//공지사항 총 개수
	@Override
	public int count() throws Exception {
		// TODO Auto-generated method stub
		return sql.selectOne(namespace + ".count");
	}






	


	
}


페이징

package com.book.model;

public class PagingVO {			// 시작값과 끝값
	
	private int page;
	private int perPageNum;		// 한 페이지에 나올 게시글 수
	private int rowStart;		// 한 페이지 시작 게시글
	private int rowEnd;			// 한 페이지 끝 게시글
	
	public PagingVO() {
		this.page = 1;
		this.perPageNum = 10;
	}

	public int getPage() {
		return page;
	}

	public void setPage(int page) {
		if (page <= 0) {
			this.page = 1;
			return;
		}
		
		this.page = page;
	}

	public int getPerPageNum() {
		return perPageNum;
	}

	public void setPerPageNum(int perPageNum) {
		if (perPageNum <= 0 || perPageNum > 100) {
			this.perPageNum = 10;
			return;
		}
		
		this.perPageNum = perPageNum;
	}

	public int getRowStart() {
		rowStart = ((page - 1) * perPageNum) + 1;
		return rowStart;
	}

	public void setRowStart(int rowStart) {
		this.rowStart = rowStart;
	}

	public int getRowEnd() {
		rowEnd = rowStart + perPageNum - 1;
		return rowEnd;
	}

	public void setRowEnd(int rowEnd) {
		this.rowEnd = rowEnd;
	}
	
	public int getPageStart() {
		return (this.page - 1) * perPageNum;
	}
	
	@Override
	public String toString() {
		return "PagingVO [page=" + page + ", perPageNum=" + perPageNum + ""
				+ ", rowStart=" + getRowStart() + ", rowEnd=" + getRowEnd()
				+ "]";
	}
	
}
package com.book.model;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.springframework.web.util.UriComponents;
import org.springframework.web.util.UriComponentsBuilder;

public class PageMakerVO {		// 페이지 블럭 처리
	
	private int totalCount;		// 게시물 총 수
	private int startPage;		// 현재 페이지 시작 번호 (1, 11, 21 등)
	private int endPage;		// 현재 페이지 끝 번호 (10, 20, 30 등)
	private boolean prev;		// 이전 페이지로 이동하는 링크 존재 여부
	private boolean next;		// 다음 페이지로 이동하는 링크 존재 여부
	
	private int displayPageNum = 10;
	
	private PagingVO pVO;		// PagingVO DTO
	
	public void calcData() {
		endPage = (int) (Math.ceil(pVO.getPage() / (double)displayPageNum) * displayPageNum);
		  startPage = (endPage - displayPageNum) + 1;
		  
		  int tempEndPage = (int) (Math.ceil(totalCount / (double)pVO.getPerPageNum()));
		  if (endPage > tempEndPage)
		  {
		   endPage = tempEndPage;
		  }
		  prev = startPage == 1 ? false : true;
		  next = endPage * pVO.getPerPageNum() >= totalCount ? false : true;
	}
	
	// perPageNum 파라미터가 주소창에 뜨도록
	public String makeQuery(int page) {
		UriComponents uriComponents = UriComponentsBuilder.newInstance()
									  .queryParam("page", page)
									  .queryParam("perPageNum", pVO.getPerPageNum())
									  .build();
		
		return uriComponents.toUriString();
	}
	
	// searchType과 keyword 파라미터가 주소창에 뜨도록
	public String makeSearch(int page) {
		UriComponents uriComponents = UriComponentsBuilder.newInstance()
									  .queryParam("page", page)
									  .queryParam("perPageNum", pVO.getPerPageNum())
									  .queryParam("searchType", ((SearchPagingVO)pVO).getSearchType())
									  .queryParam("keyword", encoding(((SearchPagingVO)pVO).getKeyword()))
									  .build();
		
		return uriComponents.toUriString();
	}
	
	private String encoding(String keyword) {
		if(keyword == null || keyword.trim().length() == 0) {
			return "";
		} try {
			return URLEncoder.encode(keyword, "UTF-8");
		} catch(UnsupportedEncodingException e) {
			return "";
		}
	}
	
	public int getTotalCount() {
		return totalCount;
	}
	public void setTotalCount(int totalCount) {
		this.totalCount = totalCount;
		calcData();
	}
	public int getStartPage() {
		return startPage;
	}
	public void setStartPage(int startPage) {
		this.startPage = startPage;
	}
	public int getEndPage() {
		return endPage;
	}
	public void setEndPage(int endPage) {
		this.endPage = endPage;
	}
	public boolean isPrev() {
		return prev;
	}
	public void setPrev(boolean prev) {
		this.prev = prev;
	}
	public boolean isNext() {
		return next;
	}
	public void setNext(boolean next) {
		this.next = next;
	}
	public int getDisplayPageNum() {
		return displayPageNum;
	}
	public void setDisplayPageNum(int displayPageNum) {
		this.displayPageNum = displayPageNum;
	}
	public PagingVO getpVO() {
		return pVO;
	}
	public void setpVO(PagingVO pVO) {
		this.pVO = pVO;
	}

}

0
  • 답변 2

  • 워르송
    346
    2020-11-18 03:02:07

    음 .. 다른분들 보실수잇게 


    전체적인 코드말고


    어디부분이 에러있는지 적어주시면 더 좋은답변 받을수있지않을까 싶습니다..


    예를들어 페이징 자체가 생성이 안된다던지


    페이징 갯수가 안맞는다던지 이런식으로여

  • htofu
    281
    2020-11-18 09:57:22
    PageMakerVO 에 정의된 int 변수도 초기화를 시켜주세요.
  • 로그인을 하시면 답변을 등록할 수 있습니다.