2022. 3. 21. 08:00ใ๊ฐ๋ ์ ๋ฆฌ ์์ ์ค/๋ฌธ์ ์ ๋ฆฌ
โ ๏ธ ๋ฌธ์ ๋ฐ์!
์ต์ด ์ฃผ๋ํ๋์ ๊ฒ์ํ ๊ธ ๋ฑ๋ก์ด ์ ๋๋์ง ํ์ธํ๊ธฐ ์ํด ์์ ๊ฐ์ด ๊ธ์ ์์ฑํ ๊ฒ์ด์์.
์ค์?! ๊ทผ๋ฐ ๊ฒ์๊ธ์ด ๋ฑ๋ก๋์ง ์๋ ๊ฒ์ด์์!
๋ฌด์์ด ๋ฌธ์ ์ผ์ง ์์๋ณด๊ธฐ ์ํด ๊ฐ๋ฐ์ ๋ชจ๋์ Console Log๋ฅผ ์ดํด๋ณด๊ธฐ ์์ํ ๊ฒ์ด์์.
Back End์๊ฒ post๋ก Request๋ฅผ ๋ณด๋๋๋ฐ, Server ์น๊ตฌ๊ฐ ๋ฌธ์ ๊ฐ ์๋ค๋ฉด์ ํด์ง๋ฅผ ๋์๋๋ด์!
๋๋์ฒด ๋ฌด์์ด ๋ฌธ์ ์ด๊ธธ๋? Back End๋ ํด์ง๋ฅผ ๋์ ๊ฒ์ผ๊น์?
InqrySn : 0
InqryUserSn : 0
fileSn : 0
inqryCn : ๋ชจ๋๋ค ํ๋ณตํ์ธ์!!!!!
secretAt : null
answerAt : null
answerCn : null
answerUserSn : 0
answerDt : null
creatDt : null
crtrSn : 0
updtDt : null
updusrSn : 0
inqrySj : ์๋
ํ์ธ์! ์ฃผ๋ํ๋ ์
๋๋ค!
srchWord : null
srchType : null
userId : null
beforeInqrySn : 0
beforeInqrySj : null
nextInqrySn : 0
nextInqrySj : null
inqryIndex : 0
answerUserId : null
2022-03-19 16:58:08.012 INFO 1356 --- [nio-8080-exec-7] c.d.j.c.support.DevInquryController : devInquryVO ๊ฐ : DevInquryVO(InqrySn=0, InqryUserSn=0, fileSn=0, inqryCn=๋ชจ๋๋ค ํ๋ณตํ์ธ์!!!!!, secretAt=null, answerAt=null, answerCn=null, answerUserSn=0, answerDt=null, creatDt=null, crtrSn=0, updtDt=null, updusrSn=0, inqrySj=์๋
ํ์ธ์! ์ฃผ๋ํ๋ ์
๋๋ค!, srchWord=null, srchType=null, userId=null, beforeInqrySn=0, beforeInqrySj=null, nextInqrySn=0, nextInqrySj=null, inqryIndex=0, answerUserId=null)
2022-03-19 16:58:08.014 INFO 1356 --- [nio-8080-exec-7] c.d.j.c.support.DevInquryController : ๋ฑ๋กํ ๊ธ์ด ๋น๋ฐ๊ธ์ธ์ง ํ์ธ ํ๊ฒ ์ต๋๋ค!
2022-03-19 16:58:08.015 INFO 1356 --- [nio-8080-exec-7] c.d.j.c.support.DevInquryController : ๊ฒ์๊ธ ๋ฑ๋ก / ์์ ์ ๋ฌธ์ ๊ฐ ๋ฐ์(๊ถํ ๋ฌธ์ )ํ์ฌ catch๋ฌธ์ด ์คํ ๋์์ต๋๋ค!
2022-03-19 16:58:08.017 WARN 1356 --- [nio-8080-exec-7] c.d.j.c.support.DevInquryController : null
2022-03-19 16:58:08.017 INFO 1356 --- [nio-8080-exec-7] c.d.j.c.support.DevInquryController : Logic์ด Error๋ก 401 Code๋ฅผ Map result์ ๋ฃ๊ฒ ์ต๋๋ค!
java.lang.NullPointerException
at com.devcommunity.junyharang.controller.support.DevInquryController.devInquryRegist(DevInquryController.java:91)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:150)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:117)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
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:1067)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:963)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1006)
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:909)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:681)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:883)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:227)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:117)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:189)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:162)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:197)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:540)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
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:359)
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:399)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:889)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1735)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:829)
์์๋ Back End์์ ํ์ธํ Exception ๋ด์ฉ์ธ ๊ฒ์ด์์.
๊ทธ ๋ฌด์๋ฌด์ํ NPE(Null Point Exception)์ด ํฐ์ ธ ๋ฒ๋ฆฐ ๊ฒ์ด์์!
์๋ ์ ๋ชฉ๊ณผ ๋ด์ฉ์ ๋ค ๋ฃ์ด์ ๋ณด๋๋๋ฐ, ๋๋์ฒด ์? NPE๊ฐ ๋ฐ์ํ๋ ๊ฒ์ผ๊น์?
/**
* ๊ฒ์๊ธ ๋ฑ๋ก / ์์ ์๋น์ค
* @param devInquryVO - ํ์ ๊ฐ์
์ ์ํ ์ด์ฉ์ ์
๋ ฅ๊ฐ์ ๋ด์ DTO
* @return Object - ์๋ฒ ์ฒ๋ฆฌ ์ฌ๋ถ์ ํด๋นํ๋ Status Code ๋ฐ Data ๋ฐํ์ ์ํ ๊ฐ์ฒด
* @see ""
*/
// TODO - Controller์ ์๋ ๋น์ฆ๋์ค ๋ก์ง ServiceImpl๋ก ์ฎ๊ฒจ์ผ ํ๋ฉฐ, ๋ฑ๋ก / ์์ ๋ถ๋ฆฌ ์์
ํ์
@ResponseBody @PostMapping("/devInqury")
public Object devInquryRegist(@RequestBody DevInquryVO devInquryVO, HttpServletRequest request) throws Exception {
log.info("devInquryRegist(@RequestBody DevInquryVO devInquryVO, HttpServletRequest request)๊ฐ ํธ์ถ ๋์์ต๋๋ค!");
log.info("Client์์ ๋์ด์จ Data Value๋ฅผ ๋จผ์ ํ์ธ ํ๊ธฐ ์ํด ๋ฐฐ์ด ๋ณ์์ ๊ฐ์ ๋ฃ๊ฒ ์ต๋๋ค!");
Field[] fields = devInquryVO.getClass().getDeclaredFields();
log.info("๋ฐ๋ณต๋ฌธ์ ํตํด ๋ฐฐ์ด์ ๋ค์ด ๊ฐ Data๋ฅผ ํ๋์ฉ ๊บผ๋ด ํ์ธ ํด ๋ณด๊ฒ ์ต๋๋ค!");
for (Field field : fields) {
/** ์ฐธ๊ณ ์๋ฃ
* @see "https://tyboss.tistory.com/entry/Java-%EC%9E%90%EB%B0%94-%EB%A6%AC%ED%94%8C%EB%A0%89%EC%85%98-reflection-setAccessible"
*/
log.info("Java ๋ฆฌํ๋ ์
๊ธฐ๋ฒ ์ค setAccessible(true) ํตํด Field ๊ฐ์ฒด ์๋ฃํ Type field์ ์ ๊ทผ์ ์ด ์ง์์์ ์ํ ์ ์ด๋ฅผ ๋ณ๊ฒฝ ํ๊ฒ ์ต๋๋ค!");
field.setAccessible(true);
System.err.println(field.getName() + " : " + field.get(devInquryVO));
} // for (Field field : fields) ๋
Map<String, Object> result = new HashMap<>();
log.info("devInquryVO ๊ฐ : " + devInquryVO.toString());
try {
log.info("๋ฑ๋กํ ๊ธ์ด ๋น๋ฐ๊ธ์ธ์ง ํ์ธ ํ๊ฒ ์ต๋๋ค!");
if (devInquryVO.getSecretAt().equals("false")) {
log.info("๋ฑ๋กํ ๊ธ์ด ๋น๋ฐ๊ธ์ด ์๋๋๋ค! ๊ณต๊ฐ๊ธ๋ก ๋ฑ๋ก ํฉ๋๋ค!");
devInquryVO.setSecretAt("N");
} else {
log.info("๋ฑ๋กํ ๊ธ์ด ๋น๋ฐ๊ธ ์
๋๋ค! ๋น๋ฐ๊ธ๋ก ๋ฑ๋ก ํฉ๋๋ค!");
devInquryVO.setSecretAt("Y");
} // if (devInquryVO.getSecretAt().equals("false")) - else ๋
log.info("๋ฑ๋ก / ์์ ํ๋ณ์ ์ํด ๋ฑ๋ก ์์ฒญ์ ๊ฒ์๊ธ ์ผ๋ จ๋ฒํธ๊ฐ ์๋์ง ํ์ธ ํ๊ฒ ์ต๋๋ค!");
// TODO : ๋ฑ๋ก / ์์ Logic ๋ถ๋ฆฌ ํ์
if (CustomStringUtil.getString(devInquryVO.getInqrySn()) == "" || devInquryVO.getInqrySn() == 0) {
log.info("๋ฑ๋ก ์์ฒญ ๊ฒ์๊ธ ์ผ๋ จ๋ฒํธ๊ฐ ๋น์ด์์ต๋๋ค! ๊ฒ์๊ธ ๋ฑ๋ก์ ์ํ ํฉ๋๋ค!");
// TODO - ํ์๊ฐ์
๋ฐ ๋ก๊ทธ์ธ ๋ก์ง ๊ตฌํ ๋ค ์๋ ํ๋์ฝ๋ฉ ์์ ํ์
devInquryVO.setInqryUserSn(4);
log.info("devInquryService.devInquryInsertUpdate(devInquryVO)์ ํธ์ถ ํ๊ฒ ์ต๋๋ค!");
devInquryService.devInquryInsert(devInquryVO);
log.info("Map result์ ๊ฒ์๊ธ ์ผ๋ จ ๋ฒํธ๋ฅผ ๋ฃ๊ฒ ์ต๋๋ค!");
result.put("resultSn", devInquryVO.getInqrySn());
} else {
log.info("๋ฑ๋ก ์์ฒญ ๊ฒ์๊ธ ์ผ๋ จ๋ฒํธ๊ฐ ์กด์ฌ ํฉ๋๋ค! ๊ฒ์๊ธ ์์ ์ ์ํ ํฉ๋๋ค!");
log.info("devInquryService.devInquryInsertUpdate(devInquryVO)์ ํธ์ถ ํ๊ฒ ์ต๋๋ค!");
devInquryService.devInquryUpdate(devInquryVO);
log.info("Map result์ ๊ฒ์๊ธ ์ผ๋ จ ๋ฒํธ๋ฅผ ๋ฃ๊ฒ ์ต๋๋ค!");
result.put("resultSn", devInquryVO.getInqrySn());
} // if (CustomStringUtil.getString(devInquryVO.getInqrySn() == "" || devInquryVO.getInqrySn() == 0)) - else ๋
log.info("Logic์ด ์๋ฃ ๋์์ผ๋ฏ๋ก, 200 Code๋ฅผ Map result์ ๋ฃ๊ฒ ์ต๋๋ค!");
result.put("code", 200);
} catch (Exception e) {
log.info("๊ฒ์๊ธ ๋ฑ๋ก / ์์ ์ ๋ฌธ์ ๊ฐ ๋ฐ์(๊ถํ ๋ฌธ์ )ํ์ฌ catch๋ฌธ์ด ์คํ ๋์์ต๋๋ค!");
e.printStackTrace();
log.warn(e.getMessage());
log.info("Logic์ด Error๋ก 401 Code๋ฅผ Map result์ ๋ฃ๊ฒ ์ต๋๋ค!");
result.put("code", 401);
return result;
} // try - catch ๋
return result;
} // devInquryRegist(@RequestBody DevInquryVO devInquryVO, HttpServletRequest request) ๋
์์ Code๋ Q&A ๊ฒ์ํ์ ๊ธ ๋ฑ๋ก / ์์ ์ ์ฒ๋ฆฌํ๋ Router(API / Controller)์ ๋ด์ฉ์ธ ๊ฒ์ด์์.
Exception ๋ด์ฉ์ ์ดํด๋ณด๋ฉด ๋ฐ๋ก 91๋ฒ์งธ ์ค์์ NPE๊ฐ ํฐ์ง ๊ฒ์ด์์.
๋น๋ฐ๊ธ..? ๋น๋ฐ๊ธ Check๋ฅผ ์ํ๋ค๋ฉด ๊ณต๊ฐ๊ธ๋ก ๋ฑ๋กํ๋ฉด ๋ ๊ฒ์ธ๋ฐ ์ ์ด๋ฌ๋ ๊ฒ์ผ๊น? ๋ผ๋ ๊ณ ๋ฏผ์ด ์๊ธด ๊ฒ์ด์์.
๐ค ์์ธ ๋ถ์
์ฐ์ธก์ vue ๊ฐ๋ฐ์ ๋ชจ๋๋ฅผ ๋ณด๋ฉด devInquryData์ seceatAt์ ๋ํ ๋ด์ฉ์ด ๋ณด์ด์ง ์๋ ๊ฒ์ด์์.
์ด ๋ฌธ์ ์ ์์ธ์ '๋น๋ฐ๊ธ' ์ด๋ผ๋ <input>์ผ๋ก ๋ง๋ค์ด์ง checkbox๋ฅผ click์ ํ๋ฒ๋ ํด์ฃผ์ง ์์ผ๋ฉด ์๋ฌด ๊ฐ๋ ๋ค์ด๊ฐ์ง ์๋ null์ด ๋์ด ๋ฒ๋ฆฌ๋ ๋ฌธ์ ์ธ ๊ฒ์ด์์.
BackEnd์์๋ NPE์ ๋ํ Check๋ ์๊ณ , ํด๋น secretAt์ ๊ฐ์ด false์ธ์ง true์ธ์ง๋ง ํ์ธ์ ํ๋ ๊ฒ์ด์์.
๊ทธ๋ ๊ธฐ ๋๋ฌธ์ NPE๊ฐ ๋ฐ์ํด ๋ฒ๋ฆฐ ๊ฒ์ด์์.
ํ์ง๋ง, ์์ Code๋ฅผ ๋ณด๋ฉด secretAt์ false๊ฐ์ด ๋ค์ด๊ฐ๋๋ก :checked ์์ฑ์๋ ๋ฃ์ด์ฃผ๊ณ , v-model์๋ ๋ฃ์ด์ค์ Data๋ฅผ Bindding ํด ์ฃผ์์ง๋ง, ๋ฌธ์ ๋ ํด๊ฒฐ ๋์ง ์์ ๊ฒ์ด์์.
๐ป ๋ฌธ์ ํด๊ฒฐ!
์ฃผ๋ํ๋์ ๊ฒฐ๊ตญ ์ด๊ธฐํ ๋น์์ ์์ false ๊ฐ์ ๋ฃ์ด ๋ฒ๋ฆฌ๋ ๋ฐฉ๋ฒ์ ์ ํํ ๊ฒ์ด์์.
146๋ฒ์งธ ์ค์ ๋ณด๋ฉด devInquryData ๊ฐ์ฒด(Object)์ secretAt์ด๋ฆ์ ๊ฐ์ง ๊ฐ์ฒด์ ์ด๊ธฐํ ๊ฐ์ `false`๋ก ๋ฃ์ด์ค ๊ฒ์ด์์.
์ด๋ ๊ฒ ๋ฌธ์ ๊ฐ ํด๊ฒฐ๋ ๊ฒ์ด์์.