https://hcl-yeon.tistory.com/67

 

java.lang.NullPointerException

Cannot invoke "String.equals(Object)" because "edit" is null    Null Pointer, 생각보다 쉽게 보는 오류다보니 해결도 쉬워서 그렇게 어려운 에러는 아니었는데 생각보다 꽤 애먹었던 부분이 있어 기록으로

hcl-yeon.tistory.com


   null값 처리에 대해서는 아직도 미숙한 점이 많은 모양이다. 오류노트를 작성한 이후에도 Null값에 대한 처리가 서툴러 종종 에러를 발생시키고 있는데 이 null의 처리에 관하여 자세히 알아보려고 한다.

 

   일단 String은 데이터 타입이 아니라 객체이다. 여기서 말하는 데이터 타입은 정수형, 실수형, 문자 등 Java에서 제공하는 변수를 담는 데이터 형식을 뜻한다. int, double, char 등등... 하지만 이런 형식만 있는 것이 아니라 Integer과 같이 부모 요소로 보이는 대문자를 가진 객체형이 존재한다. 이는 정말로 객체였으며, 오늘은 이 둘의 차이에 대해 말해보려 한다.

 

   일단 int, double, long 등과 같은 데이터 타입은 기본 데이터 타입이라고 부른다. 이는 메모리에 직접 값이 저장되는 형식이며 이 데이터 타입의 경우에는 Null값을 가질 수 없다. 반면에 Integer, Long과 같이 대문자로 시작하는 래퍼 클래스는 문자 그대로 객체기 때문에 이는 null값을 허용할 수 있다. 그리고 해당 객체가 가진 함수 또한 사용할 수 있기 때문에 형변환을 하는 경우에는 이 점이 더 유리할 수 있겠다.

 

   따라서 내가 계속 내고 있는 null point Exception 에러의 발생경위를 다시 돌아보도록 하겠다.

boolean  error = ( boolean )request.getAttribute("error");

 

   JSP 페이지에서 특정 코드에 따라 페이지를 바꾸기 위해 리퀘스트에서 값을 꺼내던 중이었다. 그리고 만약 코드의 값이 없다면 그냥 무시하겠지 싶어서 그대로 실행했지만 결과는 다음과 같았다.

 

java.lang.NullPointerException: Cannot invoke
"java.lang.Boolean.booleanValue()" because "error" is null

 

 

   null값이 오는 건 알고 있었다. 따라서 해당 값이 null이면, 다른 처리를 하라고 예외까지 지시해 둔 상황이었는데도 해당 값은 null이라는 이유로 아예 코드 실행조차 되지 않고 페이지가 터져나가고 있었다. 분명 null이면 하지말라고 예외까지 주었는데도, 그냥 변수 자체에 담지 못한다고 뻗어버린 것이었다. 그래서 오늘자 오류노트가 생긴 것이 아닐까 싶다...

 

   이유인 즉슨 간단했다, 이후 null처리를 하던 말던 일단 boolean이라는 데이터 타입은 null값 자체를 저장할 수 없으므로 애초부터 잘못된 코드라며 터지고 있는 것이었다. 따라서 내가 정한 예외처리와 함께 문제없이 진행되기 위해서는 래퍼 클래스에 담을 필요가 있다.

Boolean  error = ( Boolean )request.getAttribute("error");

 

   위와 같이 래퍼 클래스인 Boolean에 값을 저장하게 되면 null값도 자연스레 받을 수 있게되고, Boolean객체에서 null은 곧 false가 되므로 이후의 제어문에서도 별도의 null값 처리가 아닌 true/false 처리로 진행할 수 있게 되었다.

 

 

'오류노트' 카테고리의 다른 글

webflow Http Status 404 Error  (0) 2024.11.11
mySQL update 및 delete가 안될 때  (0) 2024.11.10
Tiles.xml 설정 주의 사항  (0) 2024.11.09
Downloading external resources is disabled  (0) 2024.11.08
java.lang.NullPointerException  (0) 2024.10.29

   Spring을 배우던 중, webflow에서 발생했던 404 에러를 두시간 가까이 해결하지 못했었다. 사유는 404, 그저 매핑이 되지 않는다는 이유였는데 지금까지 배워 오면서 매핑이 안되는 이유? 그런 기초적인 것을 놓칠 리 없다는 생각 때문인지 도저히 해결방안을 찾지 못했었다. 하지만 이는 webflow에 대해 완벽히 이해하지 못해서 생긴 일이었는데...

 

   일단 먼저 요청 주소를 살펴보자.

	<div>
		<form:form name="clearForm" method="delete">
			<a href="javascript:clearCart()" class="btn btn-danger pull-left">삭제하기</a>
		</form:form>
		<a href="<c:url value="/order?cartId=${cartId}"/>"
		class="btn btn-success float-right">주문하기</a>
	</div>

 

   여기서 주문하기에 연결된 주소가 webflow 주소였다. 하지만 이걸 작성하면서도 이를 어떻게 webflow에 연결된다는 건지 이해하지 못했는데 아니나 다를까, 스스로도 매핑될 컨트롤러를 몰라서인지 404 에러가 열심히 떠주며 연결할 수 없다고 못을 박아버리는 것... 찾다가 찾다가 다시 초기로 돌아가 xml 설정 파일로 돌아가 보았다.

<webflow:flow-registry id="flowRegistry" flow-builder-services="flowBuilderServices">
	<webflow:flow-location path="/WEB-INF/flows/order/order-flow.xml"></webflow:flow-location>
</webflow:flow-registry>

 

   웹 플로우를 지정하는 곳을 잘 살펴보니...

   매핑을 받을 부분을 정해주지 않았던 것이었다...

<webflow:flow-location path="/WEB-INF/flows/order/order-flow.xml" id="order"></webflow:flow-location>

 

   여기서 id 부분이 매핑되는 주소가 되는 것을 기억하자... 404는 매핑을 아예 시켜주지 않기 때문에 코드의 흐름을 읽어낼 방법이 없어 500이든 501이든 서버측에서 터지는 에러보다 더 곤란할 때가 있는 것 같다.

'오류노트' 카테고리의 다른 글

Java의 Null 처리에 관하여  (0) 2024.11.12
mySQL update 및 delete가 안될 때  (0) 2024.11.10
Tiles.xml 설정 주의 사항  (0) 2024.11.09
Downloading external resources is disabled  (0) 2024.11.08
java.lang.NullPointerException  (0) 2024.10.29
ERROR 1175 (HY000): You are using safe update mode and you tried to delete a row without a WHERE that uses a KEY column

 

   mySQL을 처음 시작했다면 기본적으로 지정된 설정 때문에 업데이트나 삭제를 진행할 수 없다는 에러를 만날 수 있을 것이다. 이는 [Edit] > [Preferences] 탭으로 들어가 아래 사진에 체크되어 있는 항목을 해제해주면 그 때부터 정상적으로 사용할 수 있다.

 

 

'오류노트' 카테고리의 다른 글

Java의 Null 처리에 관하여  (0) 2024.11.12
webflow Http Status 404 Error  (0) 2024.11.11
Tiles.xml 설정 주의 사항  (0) 2024.11.09
Downloading external resources is disabled  (0) 2024.11.08
java.lang.NullPointerException  (0) 2024.10.29
Request processing failed; nested exception is org.apache.tiles.request.render.CannotRenderException:

 

 

   교본을 따라 작성했던 내가 발생했던 오류는 아니지만 동기분의 오류를 같이 해결하다가 발견한 것.

 

   위 오류는 Tiles에서 해당 요청을 처리할 수 없을 경우 무수한 에러를 만들어내며 파일이 깨지는 경험을 할 수 있다. 해당 오류가 발생하는 원인으로는 다음 세가지의 문제를 꼽을 수 있는데...

 

   1. 템플릿 경로 이상 : 지정된 템플릿 파일이 존재하지 않거나 잘못된 경로를 사용

   2. 설정 이상 : Tiles.xml파일 등과 같이 정의 파일의 내용이 잘못됨

   3. 의존성 문제 : 필요 라이브러리 혹은 의존성이 누락되거나 호환이 안됨

 

   이 중에서 이번 에러는 2번, 설정 이상인 것 같다.

	<definition name="books" extends="base_Template">
		<put-attribute name="title" value="Books"></put-attribute>
		<put-attribute name="heading" value="도서 목록"></put-attribute>
		<put-attribute name="subheading" value="Books List"></put-attribute>
		<put-attribute name="content" value="/WEB-INF/views/books.jsp"></put-attribute>
	</definition>

 

   위는 스프링에서 Tiles를 설정하는 xml파일의 일부이다. 원하는 파일에 필요한 정보를 바꾸는 것으로, 사실 에러가 발생 할 부분이 없지만 의외로...? subheading부분의 value값을 definition name 부분의 value값과 똑같이 적어주게 되면 console창에서 무수히 많은 에러가 치솟는 것을 볼 수 있을 것이다...

	<definition name="addBook" extends="base_Template">
		<put-attribute name="title" value="Books"></put-attribute>
		<put-attribute name="heading" value="도서 등록"></put-attribute>
		<put-attribute name="subheading" value="addBook"></put-attribute>
		<put-attribute name="content" value="/WEB-INF/views/addBook.jsp"></put-attribute>
	</definition>

 

   에러가 난 부분은 이렇게 작성되어 있었고, 여기서 subheading부분의 값을 addBook이 아닌 다른 값으로 교체하자 정상적으로 작동되는 것을 확인할 수 있었다.

<put-attribute name="subheading" value="Book Addition"></put-attribute>
<!-- 해당 Value값을 수정 -->

'오류노트' 카테고리의 다른 글

webflow Http Status 404 Error  (0) 2024.11.11
mySQL update 및 delete가 안될 때  (0) 2024.11.10
Downloading external resources is disabled  (0) 2024.11.08
java.lang.NullPointerException  (0) 2024.10.29
Type mismatch & Cannot cast  (0) 2024.10.27
다운로드 외부 리소스가 비활성화되어 있습니다.

 

 

   xml파일에서 외부 리소스 링크를 삽입하면 알아서 dtd 혹은 xsd파일을 다운받게 되어 있는데, 이는 이클립스 자체 내에서 기본적으로(아마도) 비활성화 되어 있는 부분이라 처음 환경설정 할 때 풀어주어야 한다. 상단에서 [Window] - [Preferences] 에 들어간 후, 왼쪽 목록에서 XML (Wild Web Developer) 항목을 선택한다. 그리고 Download external resources like referenced DTD, XSD 항목을 체크해주면 xml에 명시된 파일들을 다운받을 수 있다.

 

   하지만 이렇게 설정 했음에도 간혹 알 수 없는 오류로 해당 파일 다운로드에 실패할 때가 있다. 이는 외부에서 파일을 다운 받는 도중 인터넷이 불안정하거나 혹은 처리하는 과정에서 데이터가 꼬이면서 원활하게 데이터를 다운받는 데 실패하여 xml파일 자체가 먹통이 되는 경우인데 이럴 때는 해당 외부 리소스 파일이 어디에 다운받아지는 지 알고 있으면 간단하다!

 

C:\Users\PC\.lemminx\cache\http\www.springframework.org\schema

 

   사용자의 C드라이브 내 Users(사용자)항목을 따라 들어가면 숨겨진 폴더 lemminx에서 해당 경로로 찾아 들어가게 되면 xml파일에서 다운받은 외부라이브러리를 확인할 수 있다. schema폴더에 사용하고자 하는 xsd파일이 제대로 들어있는지 확인하고, 오류가 나는 파일을 확인하여 그냥 제거후 다시 xml을 실행하면 정상적으로 다운받는 것을 확인할 수 있다.

 

   schema 오류는 대부분 위와 같은 자잘한 이유로 오류를 발생시키는데, 이 외에 xml에서 발생할 수 있는 오류로는 서블렛 버전과 톰캣사양에 따른 DTD설정(호환성)을 확인해 보는 것이 좋다.

 

 

버전(Version)별로 DTD선언 정리 in web.xml

web.xml은 웹서버의 환경설정을 담는 곳으로써 , '배포 설명자'라고도 하며, 웹서버를 구성하는 웹 컴포넌트들에 대한 구성 및 자원의 관계 설정 정보 등을 기술합니다. 특히 URL이 을 어떻게 처리

sayit.tistory.com

 

 

'오류노트' 카테고리의 다른 글

webflow Http Status 404 Error  (0) 2024.11.11
mySQL update 및 delete가 안될 때  (0) 2024.11.10
Tiles.xml 설정 주의 사항  (0) 2024.11.09
java.lang.NullPointerException  (0) 2024.10.29
Type mismatch & Cannot cast  (0) 2024.10.27

 

Cannot invoke "String.equals(Object)" because "edit" is null

 

   Null Pointer, 생각보다 쉽게 보는 오류다보니 해결도 쉬워서 그렇게 어려운 에러는 아니었는데 생각보다 꽤 애먹었던 부분이 있어 기록으로 남기고자 한다. 보통 널포인터 오류가 나면 참조변수에 아무것도 없겠거니 하고 대수롭지 않게 여겨서 이런 상황이 발생했다 생각한다.

 

	<ul class="nav nav-pills">
      	<!-- R : 전체상품 불러오기 -->
	  	<li class="nav-item"><a class="nav-link"  href="products">All Book</a></li>
	  	<!-- C : 상품입력 -->
		<li class="nav-item"><a class="nav-link" href="AddBook">Add Book</a></li>
		<!-- U : 상품수정 -->
		<li class="nav-item"><a class="nav-link" href="products?edit=update">Book update</a></li>
		<!-- D : 상품삭제 -->
		<li class="nav-item"><a class="nav-link" href="products?edit=delete">Book delete</a></li>
	</ul>

 

   먼저 요청 부분이다. products에 매핑할 때 수정과 삭제는 각각 파라미터를 지정해주었다.

 

	<% String edit = (String) request.getParameter("edit"); %>

	<div class="p-5 mb-4 bg-body-tertiary rounded-3">
		<div class="container-fluid py-5">
			<h1 class="display-5 fw-bold">
				<% if(edit.equals("update")){ %> 도서 편집
				
				<% } else if(edit.equals("delete")){ %> 도서 삭제
				
				<% } else { %> 도서 목록 <% } %>
			</h1>
			<p class="col-md-8 fs-4">
				<% if(edit.equals("update") || edit.equals("delete"))
				{ out.print("BookEdit"); }
				else { out.print("BookList"); } %>	
			</p>
		</div>
	</div>

 

   그리고 Null에러가 발생한 위치이다. 단순히 넘어온 파라미터를 String 변수에 담아 equals() 함수를 사용하여 조건문을 통해 요청에 맞는 데이터가 출력되도록 작성했는데 에러가 발생했다. 그것도 이상하게 편집과 삭제 페이지는 정상적으로 작동했지만 아무것도 없는 전체 목록 조회에서만 오류가 생겼는데 이유를 찾아보니 좀 더 명확하게 표시하라는 조언을 듣고 Null값을 직접 입력하기로 했다.

 

	<%  Stirng edit = null;
    
		if(request.getAttribute("edit")!=null){
			edit = (String)request.getAttribute("edit");
		}
	%>

	<div class="p-5 mb-4 bg-body-tertiary rounded-3">
		<div class="container-fluid py-5">
			<h1 class="display-5 fw-bold">
				<% if(edit.equals("update")){ %> 도서 편집
				
				<% } else if(edit.equals("delete")){ %> 도서 삭제
				
				<% } else if(edit==null) { %> 도서 목록 <% } %> 
			</h1>
			<p class="col-md-8 fs-4">
				<% if(edit.equals("update") || edit.equals("delete"))
				{ out.print("BookEdit"); }
				else { out.print("BookList"); } %>	
			</p>
		</div>
	</div>

 

   위와 같이 수정했는데 당연하게도 되지 않았다 ^0^…

 

   그래서 진짜 이유를 살펴보니, String은 저번에도 말했다싶이 일반 변수가 아니라 객체다. 즉 edit은 참조변수가 되며, 참조변수에 아무런 주소값을 가지고 있지 않은 상태에서 equals() 함수 를 실행하려 했기 때문에 에러가 뜨는것! 실제로 맨 처음처럼 작성했더니 JSP페이지 자체에서도 DeadCode라고 주의를 주었다. 하지만 이게 왜 안되는지 이해를 못했으니 실행했고 결과는 500페이지가 반겨주었다.

 

   쉽게 말해 null인 상태에서 equals() 함수 자체가 실행되지 않으니 조건식에서 에러가 발생한 경우였다. equals() 함수는 일단 String객체를 받지 않았기 때문에 그 함수를 실행하려하니 동작하지 않는 것.

   (단, edit != null 같이 입력하면 당연하게도 작동이 된다)

 

	<%  Stirng edit = "main";
    
		if(request.getAttribute("edit")!=null){
			edit = (String)request.getAttribute("edit");
		}
	%>

	<div class="p-5 mb-4 bg-body-tertiary rounded-3">
		<div class="container-fluid py-5">
			<h1 class="display-5 fw-bold">
				<% if(edit.equals("update")){ %> 도서 편집
				
				<% } else if(edit.equals("delete")){ %> 도서 삭제
				
				<% } else { %> 도서 목록 <% } %> 
			</h1>
			<p class="col-md-8 fs-4">
				<% if(edit.equals("update") || edit.equals("delete"))
				{ out.print("BookEdit"); }
				else { out.print("BookList"); } %>	
			</p>
		</div>
	</div>

 

   다시 원인을 파악했으니 기존 JSP화면에 edit참조변수에 "main"이라는 값을 저장하고 실행하니 무사히 화면이 로드되는 것을 확인할 수 있었다. String객체에 대해 이제 완벽하게 다 안다고 생각했는데 이런 오류를 통해 다시 기초부터 열심히 해야겠다는 생각이 들었다...

'오류노트' 카테고리의 다른 글

webflow Http Status 404 Error  (0) 2024.11.11
mySQL update 및 delete가 안될 때  (0) 2024.11.10
Tiles.xml 설정 주의 사항  (0) 2024.11.09
Downloading external resources is disabled  (0) 2024.11.08
Type mismatch & Cannot cast  (0) 2024.10.27
Type mismatch: cannot convert from int to (Data Type)

 

 

   가장 쉽게 보는 오류 중 하나로 변수에 데이터를 담을 때 형식이 맞지 않아 발생한다.

   보통 이럴 때는 데이터 타입을 잘못 지정했는지 확인해보거나, 아니면 강제로 형변환을 통해 해결하는 경우가 많다.

   잘못 지정했는지 확인하여 해결되는 것 말고, 강제로 형변환을 통하는 경우 몇가지를 알아보자.

 

		int a = 100;
		request.setAttribute("int_a", a);
		
		int b = request.getAttribute("int_a"); //에러 발생

 

   대표적으로 사용하는 예는 request객체를 활용할 때, request에 데이터를 저장하게 되면 어떤 타입이던 객체들의 조상인 Object로 저장되기 때문에 다시 꺼낼때는 무조건 Type mismatch 에러가 발생하게 된다. 이럴 때는 그냥 강제 형변환으로 받아주면 문제 없다.

		int b = (int) request.getAttribute("int_a"); //강제 형변환

 


 

Cannot cast from String to (Data Type)

 

   1 : 1 로 변환이 되는 경우가 아니라 이번에는 문자열에서 숫자 그대로 바꾸는 방법을 알아보자.

 

   위와 같은 강제 형변환은 대부분 원본을 왜곡시키며 강제로 형태를 바꾸는 것이 가능하지만 문자열에서 강제 형변환은 힘들다. 이는 String 자체가 하나의 객체기 때문에 데이터 타입으로 보기는 어렵기 때문이다. 따라서 문자열을 정수나 실수로 바꾸려 한다면 해당하는 데이터 타입 클래스의 parse~ 함수를 이용해야 한다.

		String a = "12345";
		request.setAttribute("S_a", a);
		
		int b = Integer.parseInt((String)request.getAttribute("S_a"));

 

 

'오류노트' 카테고리의 다른 글

webflow Http Status 404 Error  (0) 2024.11.11
mySQL update 및 delete가 안될 때  (0) 2024.11.10
Tiles.xml 설정 주의 사항  (0) 2024.11.09
Downloading external resources is disabled  (0) 2024.11.08
java.lang.NullPointerException  (0) 2024.10.29

+ Recent posts