백수n년차
296
2017-09-14 22:43:28
4
4030

NullPointerException 에러가 뜨는데요.


강사 등록을 누르면 다른 과목 테이블에서 과목을 찾아와 모달창에 뿌려주는 액션입니다.

그런데 문제가 에러는 뜨는데 화면에는 원하는 값이 출력됩니다.

과목을 추가해도 바로바로 적용이 되고.. 아에 실행자체가 안되야 손이라도 대보겠는데..



$(".teacherinsert").on("click", function(){
			var txt ="";
			
			$.ajax({
				url:"adminteachersub.it",
				success : function(data){
					console.log(data);
					var myObj = JSON.parse(data);
					console.log(myObj);
					$.each(myObj, function(idx, item){
						txt += "<label><input type='checkbox' value='"+item.subject_id+"'>"+item.subject_name+"</label><br>";
						
					})
					$(".subcheckbox").append(txt) 
					$("#t-insert-Modal").modal("show");
					
				}
					
			});
			
			
			
		});
		
		$("#t-insert-Modal").on("hidden.bs.modal", function(){
			$(".subcheckbox").html("")
			
		});



	public void adminteachersub(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setCharacterEncoding("UTF-8");
		
		AdminBasicDAO dao = new AdminBasicDAO();
		List<AdminBasic> result = new ArrayList<AdminBasic>();
		result = dao.sublist("all", "");
		
		
		Gson gson = new Gson();
	
		PrintWriter out = response.getWriter();
		
		out.write(gson.toJson(result));
        out.flush();
        out.close();


	}


액션이 이뤄지는 부분의 간략한 코드입니다.

혹시 AdminBasic VO에 안쓰이는 변수가 같이 보내져서 에러가 뜨나 싶어서


subject_id와 subject_name으로만 이루어진 별도의 클래스를 생성해서


해봤지만, 결과는 같습니다. 에러는 뜨지만 출력은 정상적으로 되는....


도움 좀 부탁드립니다.


9월 14, 2017 10:25:29 오후 org.apache.catalina.core.StandardWrapperValve invoke

심각: Servlet.service() for servlet [controller] in context with path [/final_project01] threw exception

java.lang.NullPointerException

at com.admin.ControllerServlet.processRequest(ControllerServlet.java:92)

at com.admin.ControllerServlet.doGet(ControllerServlet.java:32)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:622)

at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)

at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)

at com.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:20)

at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)

at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)

at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)

at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:94)

at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)

at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)

at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)

at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)

at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)

at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:502)

at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1132)

at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1533)

at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1489)

at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

at java.lang.Thread.run(Unknown Source)




밑에는 에러입니다.


0
  • 답변 4

  • 20523
    1k
    2017-09-14 22:48:44

    에러가 아주 직관적으로 보입니다.

    java.lang.NullPointerException
    	at com.admin.ControllerServlet.processRequest(ControllerServlet.java:92)
    	at com.admin.ControllerServlet.doGet(ControllerServlet.java:32)


    사용자코드(com.admin.controllerservlet)에서 92번 라인 혹은 32번 라인에서 원인을 제공했다고 보시면 되고,

    그 근처에서 문제를 해결하시면 됩니다.

    NPE 같은 경우, 32번 라인은 볼 필요가 없을 경우가 상당하고, 92번 라인에서 직관적으로 에러 원인을 찾을 수 있다고 보입니다.

    controllerservlet의 코드에서 92번 라인을 직접 확인해 보시거나, 해당 코드의 전체와 라인을 포함하여 올려주시면, 추가 조언을 드릴 수도 ...

  • 백수n년차
    296
    2017-09-14 23:13:45 작성 2017-09-14 23:31:34 수정됨

    이거답변을 어떻게 다는지 모르겠네요.

    아무튼 원인은 dgkim님 말씀을 듣고 찾아보니

    서비스클래스에서 리턴값을 안넣어주다보니 포워딩할 viewpage에 null값이 들어가는게 문제로 보입니다.

    원래 서비스클래스(mvc패턴에서는 모델이라고 하던가요?) 에는 무조건 리턴값을 넣어주는게 정석인가요?

    강사님이 알려준 ajax를 사용하기 위해 jsp 중간 경유지를 만들지 않고 나름 생각해서 다이렉트로 주고 받고 있었거든요.

    혹시 아래의 소스에서 해결방법이 있는 건가요?



    ---------------------------- 9/14/23:31 추가------------

    일단 한가지 방법으로 해결했습니다

    포워딩을 viewpage가 null 아닐때만 실행하도록 했습니다.

    이 해결방법이 맞는 건가요?

    ------------------------------------------------



    package com.admin;
    
    import java.io.IOException;
    import java.lang.reflect.Method;
    
    import javax.servlet.RequestDispatcher;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class ControllerServlet extends HttpServlet {
    
    	
    	
    	private static final long serialVersionUID = -4045243652714171905L;
    	// 확장자 문자열 저장용 임시 변수
    	private String ext;
    
    	// init() 메소드는 서블릿이 최초 실행시 자동 호출되는 메소드
    	// ->주의) 한 번만 호출되고 실행된다.
    	public void init() throws ServletException {
    
    		// web.xml 안에 있는 <init-param> 엘리먼트 정보
    		ext = getInitParameter("ext");
    
    	}
    
    	@Override
    	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		// doGet() 메소드가 처리할 내용을 사용자 정의 메소드로 넘긴다.
    		processRequest(req, resp);
    	}
    
    	@Override
    	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    		// doPost() 메소드가 처리할 내용을 사용자 정의 메소드로 넘긴다.
    		processRequest(req, resp);
    	}
    
    	// 사용자 정의 메소드 추가
    	// -> doGet() + doPost()
    	// -> 사용자 요청 방식을 구분하지 않고 하나로 통합 처리 가능.
    	private void processRequest(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		// 1. 사용자 요청(/hello.do or /test.do)에 대한 분석 처리
    		// 2. 적절한 모델 클래스 액션 요청
    		// 3. 돌려받은 결과를 뷰(JSP) 페이지로 전달
    		// -> request 객체에 결과 저장 후
    		// -> RequestDispatcher 객체를 이용한 포워딩
    
    		// 사용자 요청 주소 분석 -> 특정 메소드와 매핑
    		// 사용자 요청 주소가 /hello.do 인 경우 -> hello()
    		// 사용자 요청 주소가 /test.do 인 경우 -> test()
    		String command = request.getRequestURI();
    		// System.out.println(command); //"/프로젝트이름/test.do"
    		if (command.indexOf(request.getContextPath()) == 0) {
    			command = command.substring(request.getContextPath().length());
    			// System.out.println(command); //"/test.do"
    		}
    		command = command.substring(1, command.indexOf(ext));
    		// System.out.println(command); //"test"
    
    		// AdminServiceClass, LoginServiceClass, GuestbookServiceClass 객체의 특정 메소드
    		// 호출(invoke) 및 View 정보 반환
    		String viewPage = "";
    		try {
    			
    			if (command.startsWith("adminb")) {
    				AdminBasicService service = new AdminBasicService();
    				Method m = AdminBasicService.class.getMethod(command, HttpServletRequest.class, HttpServletResponse.class);
    				viewPage = (String) m.invoke(service, request, response);
    				
    			}
    			
    			if (command.startsWith("admint")) {
    				AdminTeacherService service = new AdminTeacherService();
    				Method m = AdminTeacherService.class.getMethod(command, HttpServletRequest.class, HttpServletResponse.class);
    				viewPage = (String) m.invoke(service, request, response);
    				
    			}
    
    			
    
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    
    		// View 페이지 포워딩
    		RequestDispatcher dispatcher = request.getRequestDispatcher(viewPage);
    		dispatcher.forward(request, response);
    
    	}
    
    }
    



    package com.admin;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.*;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import com.google.gson.Gson;
    
    public class AdminTeacherService {
    
    	// 강사관리 메인페이지
    	public String adminteachermain(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		// 액션 코드 작성
    		String key = request.getParameter("key");
    		String value = request.getParameter("value");
    
    		if (key == null) {
    			key = "all";
    			value = "";
    		}
    
    		List<AdminTeacher> teacherlist = new ArrayList<AdminTeacher>();
    		AdminTeacherDAO dao = new AdminTeacherDAO();
    
    		teacherlist = dao.teacherlist(key, value);
    		Map<String, String> teachercheck1 = new HashMap<String, String>();
    		Map<String, String> teachersubcheck = new HashMap<String, String>();
    		int a, b = 0;
    
    		for (AdminTeacher m : teacherlist) {
    			String disabled = "";
    			a = dao.teacherdelcheck1(m.getTeacher_id());
    			b = dao.teacherdelcheck2(m.getTeacher_id());
    			if (a + b != 0) {
    				disabled = "disabled";
    			}
    			teachercheck1.put(m.getTeacher_id(), disabled);
    		}
    
    		for (AdminTeacher m : teacherlist) {
    			a = 0;
    			String disabled = "";
    			a = m.getCount_();
    			if (a == 0) {
    				disabled = "disabled";
    			}
    			teachersubcheck.put(m.getTeacher_id(), disabled);
    		}
    
    		request.setAttribute("teachercheck1", teachercheck1);
    		request.setAttribute("teachersubcheck", teachersubcheck);
    		request.setAttribute("teacherlist", teacherlist);
    		request.setAttribute("key", key);
    		request.setAttribute("value", value);
    
    		// 뷰 페이지 주소 지정 -> 포워딩
    		return "/WEB-INF/view/admin/adminteacher.jsp";
    
    	}
    
    	// 강사 선택과목 호출을 위한 ajax 메소드
    
    	public void adminteachersub(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		response.setCharacterEncoding("UTF-8");
    		
    		AdminBasicDAO dao = new AdminBasicDAO();
    		List<AdminBasic> result = new ArrayList<AdminBasic>();
    		result = dao.sublist("all", "");
    		
    		
    		Gson gson = new Gson();
    	
    		PrintWriter out = response.getWriter();
    		
    		out.write(gson.toJson(result));
            out.flush();
            out.close();
    
    
    	}
    
    	// 강사관리 메인페이지
    	public String adminteacherinsert(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		// 액션 코드 작성
    		String name = request.getParameter("name");
    		String phone = request.getParameter("phone");
    		String ssn = request.getParameter("ssn");
    
    		List<AdminTeacher> teacherlist = new ArrayList<AdminTeacher>();
    		AdminTeacherDAO dao = new AdminTeacherDAO();
    
    		
    		Map<String, String> teachercheck1 = new HashMap<String, String>();
    		Map<String, String> teachersubcheck = new HashMap<String, String>();
    		int a, b = 0;
    
    		for (AdminTeacher m : teacherlist) {
    			String disabled = "";
    			a = dao.teacherdelcheck1(m.getTeacher_id());
    			b = dao.teacherdelcheck2(m.getTeacher_id());
    			if (a + b != 0) {
    				disabled = "disabled";
    			}
    			teachercheck1.put(m.getTeacher_id(), disabled);
    		}
    
    		for (AdminTeacher m : teacherlist) {
    			a = 0;
    			String disabled = "";
    			a = m.getCount_();
    			if (a == 0) {
    				disabled = "disabled";
    			}
    			teachersubcheck.put(m.getTeacher_id(), disabled);
    		}
    
    		request.setAttribute("teachercheck1", teachercheck1);
    		request.setAttribute("teachersubcheck", teachersubcheck);
    		request.setAttribute("teacherlist", teacherlist);
    
    		// 뷰 페이지 주소 지정 -> 포워딩
    		return "/WEB-INF/view/admin/adminteacher.jsp";
    
    	}
    
    }



  • 20523
    1k
    2017-09-14 23:38:23

    헐, ...

    try절 안에서 if로 command체크할 때, else일 때 갈 뷰를 넣어 주는 것이 좋을 것 같습니다.

    혹은, viewPage 초기화할 때, "" 말고 가야할 페이지를 지정해 주던가. (결과는 동일하지요? 이론상...)


  • 20523
    1k
    2017-09-14 23:40:28
    그리고 정상 처리된다기보다, .ajax에서 error? failure? callback으로 가야할 것이 안 갔다고 봐야할 것입니다.


  • 로그인을 하시면 답변을 등록할 수 있습니다.