안녕하세요 워누입니다😀

오늘 포스팅은 STS에서 새 프로젝트 생성 시 JAVA 11을 고를 수 없었던 

이상한 오류가 발생되어 기록을 남겨보고자 합니다😂

 

우선 오류 화면은 다음과 같습니다!

 

 

 

새로운 프로젝트 하나를 따기 위해서 "Spring Starter Project"를 클릭했으나..

 

 

Java Version 선택 옵션이 17과 21만 존재하더군요. 

기본 옵션은 아래 링크에서 작성한 것처럼 제대로 세팅되어 있는 상황이었구요!

 

https://seoneu.tistory.com/51

 

[JAVA/Spring Boot] STS4 기본 설정 및 첫 프로젝트 띄우기

안녕하세요 워누입니다! 지난 포스팅에 이어 이번에는 STS4 기본 설정 후 첫 프로젝트를 띄워보고자 합니다. 우선 STS4를 실행해주세요! 첫번째로 세팅할 것은 JRE 설정입니다! 이제 상단 매뉴에서

seoneu.tistory.com

 

STS를 밀고 다시 설치해보아도, Java 환경변수를 다시 설정해주어도 동일하게 11버전은 안되더라구요.

(17/21은 잘만 선택되는데 말이죠)

 

구글에 검색해도 해당 이슈에 대한 현상이 나오지 않아 여러모로 불편하던 중

Spring 공식 사이트에서 2.7.x 버전의 지원 종료에 대한 내용을 볼 수 있었습니다.

(https://spring.io/projects/spring-boot#support)

 

 

이것 때문인지 아닌지는 모르겠지만 여튼 저는 STS에서 11버전을 사용할 수 없는 상태입니다.

일단 boot 3.x 버전을 공부해보기 위해서라도 17 이상을 설치해보긴 하겠지만 

여러모로 레거시에 대한 서비스 종료가 너무 빠르게 진행된다는 건 아쉽긴 하네요ㅜㅜ

 

혹시 저와 같은 문제를 겪고 계시거나 문제를 해결하신 분이 있다면 댓글로 달아주시면 감사하겠습니다😂

(저는 결국 해결 못하고 맥에 설치한 인텔리제이로 프로젝트를 진행해보겠습니다...😅)

안녕하세요 워누입니다!

지난 포스팅에 이어 이번에는 STS4 기본 설정 후 첫 프로젝트를 띄워보고자 합니다. 

 

우선 STS4를 실행해주세요!

첫번째로 세팅할 것은 JRE 설정입니다! 

이제 상단 매뉴에서 [Windows > Reference] 를 클릭해주세요.

 

Preference 창에서 [JAVA > Installed JREs] 매뉴로 접속해보면

위와 같이 STS에 이미 설치된 JRE가 있다는 것을 알 수 있습니다.

그렇지만 저는 이전 포스팅에서 JDK를 설치했었기 때문에 설치한 JDK로 세팅을 바꾸도록 하겠습니다!

.

오른쪽 위 [Add...] 버튼을 클릭해봅시다. 

여기서 [Standard VM]을 선택하고 [Next >] 버튼을 클릭해주세요!

여기서 [Directory]를 클릭한 후 JDK가 설치된 경로의 폴더를 선택해주세요.

그러면 아래와 같이 나올 것입니다!

이제 [Finish] 버튼을 클릭해서 완료해주세요!

그럼 아래와 같이 [Preferernce] 화면으로 돌아오면서 위에서 세팅한 JDK가 함께 추가된 것을 볼 수 있습니다.

새로 설치한 JDK 옆 체크박스를 클릭한 다음 [Apply] 버튼을 클릭해주세요.

이후 왼쪽 매뉴에서 [JAVA > Compiler]를 클릭해주세요!

JDK Compliance level에서 자신이 설치한 JDK 버전과 맞는지 확인해서 수정해주세요!

저는 11버전을 설치했기 때문에 11로 수정했습니다. 

버전 수정이 완료되었다면 [Apply] 버튼을 클릭해줍시다!

.

이번에는 인코딩을 설정해보겠습니다. 

왼쪽 매뉴에서 [General > Content Types]를 클릭해줍시다. 

 

화면 내 Content types 항목 중 Text를 클릭하여 Default encoding이 어떻게 나오는지 확인해주세요!

저는 아무것도 안 떠 있어서 아래와 같이 "UTF-8"을 입력해주었습니다.

 

저처럼 입력을 직접 해주신 분이 계시다면 오른쪽 [Update] 버튼을 꼭 클릭해주세요!

 

[Text] 항목에서 "UTF-8" 적용을 완료했다 하더라도 하위 항목 중

인코딩이 제대로 설정이 안되어있는 케이스들이 있을 수 있어요.

 

저의 경우에는 [Java Properties File]과 [Spring Properties File]이 "ISO-8859-1"으로 세팅이 되어 있었습니다!

이렇게 세팅되어 있는 경우도 있으니 꼭 찾아서 "UTF-8"로 설정을 변경하고 [Update]를 클릭해주세요. 

 

다음은 [General > Workspace] 매뉴로 이동해봅시다!

저는 이미 [Text file encoding] 항목에 "Other: UTF-8"이 잘 적용되어 있었습니다!

만약 다른 인코딩으로 세팅된 분이 있다면 여기도 "UTF-8"로 수정한 다음 [Apply] 버튼을 클릭해주세요!

.

인코딩 세팅을 마무리하고, 마지막으로 [Gradle] 매뉴로 이동해보겠습니다. 

[Java home] 항목에 [Browse] 버튼을 클릭하여 JDK가 설치된 경로를 입력합니다. 

그리고 위와 같이 [Authmatic Project Synchronization] 항목에 체크가 되어 있지 않다면 체크박스 버튼을 클릭해주세요!

 

위와 같이 되었다면 세팅이 정상적으로 마무리 된 것입니다. 

이제 [Apply] 버튼을 클릭한 후 [Apply and Close] 버튼을 클릭해서 [Preference] 화면을 종료해주세요!

.

다시 처음화면으로 돌아왔네요 ㅎㅎ

이제  [Project Explorer]에서 [Create new Spring Starter Project]를 클릭해줍시다!

저는 [Type]을 "Gradle - Groovy"로, [Java Version]을 "11"로, Name은 "Sample", Package 명은 "sample"로 했습니다. 

이 글을 보고 세팅하시는 분들은 PC 환경에 맞게 세팅을 수정해주시고 [Next >] 버튼을 클릭해주세요!

여기서는 스프링 부트 버전 및 의존성을 설정할 수 있어요!

지금은 간단한 웹 프로젝트를 실행할 예정이므로 아래 두 가지만 추가해줍시다🙂

 

[Developer Tools > Spring Boot DevTools]

[Web > Spring Web]

 

다른 의존성에 대한 도구들은 나중에 알아가보도록 하고 우선 [Next] 버튼을 클릭해줍시다!

 

이 화면에서는 Spring Boot의 구성 정보를 확인할 수 있습니다. 

아직 아무것도 모르므로 일단 [Finish] 버튼을 클릭해줍시다!

 

.....? 이 오류는 무엇인가...

 

오류 메세지:

'Import Getting Started Content' has encountered a problem.

NoMatchingConfigurationSelectionException

 

해당 내용을 구글링해서 찾아보니

Spring Boot 3.x 버전으로 사용하려면 JAVA 17 버전 이상으로 세팅이 되어야 한다는군요...

 

처음 다뤄보니 별 실수를 다하는군요..😂

여러분은 저같은 실수 하지 마시고 Spring Boot 버전을 JAVA 버전에 맞게 사용하세요!!

여튼 저는 생성했던 프로젝트를 삭제하고 아래와 같이 다시 생성했습니다. 

(나중에는 JDK 17 버전 다시 설치하고 돌아오겠습니다ㅋㅋ)

처음과 다르게 Spring Boot 버전을 2.7.11로 세팅하고 프로젝트를 생성했습니다!

.

이번에는 문제 없이 정상적으로 생성이 된 것 같군요..!

그렇다면 이제 실제로 Run을 시켜보도록 하겠습니다. 

.

프로젝트를 우클릭한 상태에서 [Run As > Spring Boot App] 을 클릭해주세요!

콘솔 창을 보면 위와 같이 출력된 것을 볼 수 있습니다! 

이 중에서 5번째 줄을 살펴보자면, 

STS에 내장된 Tomcat 서버가 8080 포트로 구동되었다는 사실을 알 수가 있습니다!

그럼 이제, Browser에 접속해서 결과를 볼까요?

.

브라우저를 하나 띄워주시고 "localhost:8080"을 입력해서 접속해주세요!

 

....??? 이번엔 또 무엇인가..싶겠지만 이번에는 다행히 정상적인 결과입니다. 

프로젝트를 띄우기는 했지만 화면에 보이는 부분은 자동으로 만들어지지 않기 때문에 이런 화면이 나온 것이죠!

.

프로그래밍의 첫 관문인 "Hello World!"를 띄워보면 조금이나마 감을 잡을 수 있을 것 같네요 ㅎㅎ

 

이번엔 sample package 밑에 Controller 패키지를 생성해봅시다!

위 화면에서 sample 패키지를 우클릭 한 후 [New > Package]를 클릭합니다!

화면을 띄웠다면 [Name]에 "sample.controller"를 입력해준 후 [Finish]  버튼을 클릭합니다. 

[Finish] 버튼을 클릭하여 완료하면 아래 화면과 같이

sample 패키지 안에 controller 패키지가 추가된 것을 볼 수 있습니다!

이제 controller 패키지 밑에 HelloWorldController 클래스를 생성해봅시다!

controller 패키지 우클릭 후 [New > Class]를 클릭해주세요!

Name에만 "HelloWorldController"라고 이름합시다. 

원래 Java에서는 [public static void main(String[] args)] 항목을 추가하지만

여기서는 그럴 필요 없이 여러 어노테이션들이 대신 기능을 수행해줄겁니다 ㅎㅎ

.

[Finish] 버튼을 클릭하면 아래와 같이 나올 겁니다. 

자, 이제 여기다가 아래의 코드를 작성해볼까요?

 

package sample.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloWorldController {

	@RequestMapping("/")
	public String hello() {
		return "Hello World!";
	}
}

코드에 대하여 짤막하게 설명하자면,

@RestController 어노테이션은 REST 컨트롤러 기능을 수행하도록 하는 어노테이션이며, 

@RequestMapping 어노테이션은 해당 메서드를 실행할 수 있는 주소를 설정하는 어노테이션입니다. 

여기서는 기본 주소를 " / "로 지정하였습니다. 

 

대충 설명했지만 나중에 조금 더 복잡한 코드가 나올 때 자세히 설명드릴 수 있을 것 같아요! 

우선 작성한 코드를 가지고 다시 한 번 프로젝트를 실행하겠습니다!

로그도 정상적으로 실행이 되었구요!

무사히 "Hello World!"도 띄웠습니다!

 .

조금은 다사다난 했지만 Spring Boot의 첫 발걸음을 뗀 기분입니다! 

첫 발걸음을 떼는 다른 분들은 저보다는 덜 실수하기를 바라며 이만 글을 마치겠습니다😀

 

감사합니다!

 

안녕하세요 워누입니다!

최근에 회사에서 후임들과 소스리뷰를 진행하는데 확실히 Java를 야매(?)로 공부하다보니, 대략적으로 이 함수가 어떤 용도인지만 알고 있었을 뿐, 저 역시도 원론적인 개념이나 어떻게 사용하는지 방법 등을 정확하게 알지 못함을 다시 한번 깨닫게 되더군요.. 항상 검색하면서 공부하고 개발하다 보니 정리가 안된 것들이 많은 것 같습니다. 그래서 이번 포스팅과 다음 포스팅은 제가 개발하면서, 그리고 남이 개발한 걸 보면서 헷갈렸던 개념인 컬렉션 프레임워크(collection framework)에 대하여 작성해보도록 하겠습니다! 

.

일단 컬렉션 프레임워크(collection framework)를 정의하려면, 컬렉션(collection)과 프레임워크(framework)를 나누어서 살펴보아야 합니다. 

 

컬렉션(Collection) : 요소를 수집해서 저장하는 것을 말하며, 자바 컬렉션은 객체를 수집해서 저장하는 역할.

프레임워크(Framework) : 사용 방법을 미리 정해 놓은 라이브러리를 말함 (자주 쓰이는 말이니 꼭 알아두시길!)

 

컬렉션과 프레임워크를 정의하고 보니 컬렉션 프레임워크는 아래와 같이 정의할 수 있겠군요!

 

컬렉션 프레임워크(collection framework) : 객체를 수집해서 저장하는 역할에 대한 사용 방법이 미리 정의된 라이브러리

 

보통 저를 포함해서 초급 개발자들이 주로 하는 실수들은 객체를 저장해두고, 필요할 때 꺼내쓸 때 주로 배열을 쓰는 경우가 많습니다! 배열이 아무래도 쉽게 생성하고 사용할 수 있지만, 아무래도 저장할 수 있는 객체 수가 지정되어 있다 보니, 불특정 다수의 객체를 저장하기에는 문제가 있죠. 

(배열의 길이를 무작정 크게 생성하는 방법도 있지만 이 역시 불필요한 공간을 만들어버리는 거니까 좋은 방법이 될 수 없습니다.)

또 배열을 사용하다가 중간에 객체를 삭제하게 되면 해당 index가 비워지는데 이후에 새 객체를 만들어 저장하려면, 어디가 비어있는지 확인하는 코드를 또 만들어야 해요. 

-> 쉽게 말하면 공간 문제와 삭제 후 생성 같은 문제가 너무 커서 "배열은 비효율적이다." 라고 보시면 됩니다. 

 

이걸 해결하려고 자바는 자료구조를 바탕으로 객체들을 효율적으로 추가, 삭제, 검색(객체 수집, 저장을 포함한 역할)할 수 있도록 java.util 패키지에 인터페이스와 클래스들을 포함(라이브러리를 미리 정의해 놓음)시켜 놓았는데 이것들이 바로 컬렉션 프레임워크들입니다! 

 

글이 너무 길지만 한번 읽고 사용하면 이해가 훨씬 빠를거에요! (저도 찾아보면서 개념을 이해했습니다..3년간 뭐했니..)

 

컬렉션 프레임워크에서 사용하는 주요 인터페이스(interface)는 List, Set, Map 세가지가 있습니다.

 

이 중에서 List와 Set 인터페이스는 모두 컬렉션(Collection) 인터페이스를 상속받기 때문에 List와 Set의 공통된 부분은 컬렉션 인터페이스에서 정의하고 있는데, Map 인터페이스는 키(key)와 값(value)을 쌍으로 묶어서 관리하는 구조라서 List와 Set과는 사용방법이 완전히 다릅니다. 

 

이 인터페이스들의 특징들을 아래 표로 정리하고 구조도를 그려보았습니다.

.

인터페이스 분류 특징 구현 클래스
Collection List<E> - 순서를 유지하고 저장
- 중복 저장 가능
ArrayList, Vector, LinkedList
Set<E> - 순서를 유지하지 않고 저장
- 중복 저장 불가
HashSet, TreeSet
Map <K,V> - 키와 값이 한 쌍이 되어 저장
- 키는 중복 저장 불가
HashMap, Hashtable,
TreeMap, Properties

.

 

 

Collection Framework Diagram

.

표와 구조도에 작성된 구현 클래스들은 각 인터페이스에서 제공해주는 클래스들입니다. 인터페이스를 사용한다면 그 안에 미리 구현되어 있는 클래스들을 가져와서 사용할 수 있다는 것인데요, 이는 프레임워크를 자주 사용하다 보면 익숙해질 겁니다 ㅎㅎ 

.

오늘은 컬렉션 프레임워크에 대한 개념과 특징들을 이렇게 정리해 보았는데요! 역시 야매로 알고 있는 것보다는 직접 정리하면서 찾아보는 것이 개발할 때 많이 도움이 되는 것 같습니다 ㅎㅎ 다음 포스팅에서는 예제 소스를 가져와서 어떻게 사용하는지 정리해보도록 하겠습니다! 

 

그럼 이만~~~~!

블로거 워누입니다. 

 

지난번 포스팅에 이어 String 메소드에서 제공하는 equals에 대해서 포스팅하고자 합니다! 

equals는 문자열을 비교할 때 사용하는 메소드입니다. 이 메소드를 이용해서 서로 다른 문자열 타입 변수의 문자열을 서로 비교합니다. 

....

그런데 말입니다.. 우리가 일반적으로 변수 타입을 비교하려면 같다는 의미의 이항연산자인 "==" 연산자를 통해서 많이 비교하는데, 문자열은 굳이 equals를 쓸 필요가 있을까요?

 

 

확인을 위해 직접 실험해 보았습니다. 우리에게 늘 익숙한 Hello 시리즈로 소스코드를 만들었습니다.


[equalsPrac.java 소스코드]

public class equalsPrac {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str1 = new String("HelloJava");
		String str2 = "HelloJava";
		String str3 = "HelloJava";
		
		if(str1 == str2) 
			System.out.println("같은 문자열");
		else 
			System.out.println("다른 문자열");
		
		if(str2 == str3) 
			System.out.println("같은 문자열");
		else 
			System.out.println("다른 문자열");
		
	}

}

결과는 아래와 같이 나옵니다. 

equalsPrac.java 실행화면

.

.

.

?

분명 똑같이 비교연산자를 썼는데 str1과 str2가 왜 다른걸까요..?

(대학교에서 이 내용을 가르쳐주지 않았습니다. 교수님이 몰랐을수도...ㅎ)

 

사실 자바는 문자열 값이 완전히 똑같으면, 동일한 String 객체를 참조합니다. 즉, str2와 str3는 같은 객체라는 것인데요, 반면 str1은 new 연산자를 사용하는 바람에 다른 String 객체를 참조하게 되버린 것입니다.

 

쉽게 말하면 클래스를 하나 만들어놓고 객체를 따로 만들어놓은 것처럼 말이죠!

.

Class cl1 = new Class();

Class cl2 = new Class();.

.

대충 이런 느낌인데 여기서 cl1과 cl2는 완전히 다른 객체인 것처럼, str1과 str2, str3 사이도 마찬가지라고 합니다. 

 

이런 경우, "=="을 사용하면 다른 객체간 문자열 비교가 불가능하겠죠?

이래서 equals를 사용합니다. 

 

이번엔 지난 포스팅에서 사용했던 substring() 메소드까지 같이 써서 비교해볼게요!

 


[equalsPrac2.java 소스코드]

public class equalsPrac2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str1 = new String("Java");
		String str2 = "Java";
		String str3 = new String("HelloJava");
		String str4 = "HelloJavaProject";
		
		if(str1 == str2) 
			System.out.println("같은 String 객체를 지정");
		else
			System.out.println("다른 String 객체를 지정");
		
		if(str2.equals(str1))
			System.out.println("같은 문자열");
		else 
			System.out.println("다른 문자열");
		
		if(str3.substring(5).equals(str1))
			System.out.println("같은 문자열");
		else 
			System.out.println("다른 문자열");
		
		if(str4.substring(5,9) == str2)
			System.out.println("같은 String 객체를 지정");
		else
			System.out.println("다른 String 객체를 지정");
		
		if(str4.substring(5,9).equals(str2))
			System.out.println("같은 문자열");
		else 
			System.out.println("다른 문자열");
		
	}

}

이번 결과는 아래와 같이 나옵니다.

equalsPrac2.java 실행결과

.

어떤 느낌인지 대략 감이 오시나요..? "==" 연산자를 사용해버리면 객체의 값만 비교하는게 아니라 객체 동일 여부까지 따지게 되서, 문자열 비교할 때 원하는 값을 가져오지 못할 수도 있습니다.

이전 포스팅에서 언급한 것처럼 자바에서의 String은 단순한 문자열 타입 변수가 아닌 Class로 분류되기 때문에

문자열의 값 자체를 비교할 때는 비교 연산자 "=="이 아닌 equals() 메소드로 비교해야 정확한 값을 가져올 수 있습니다. 

(이거땜에 회사에서 쓸때없이 잡아먹은 시간이 얼만지 모르겠습니다...)

 

만약 이 글을 읽으시는 초급개발자분들은 예시를 보면서 직접 소스도 짜보고 여기저기 바꿔가면서 테스트 해보셨으면 좋겠습니다! 그래야 저처럼 버리는 시간 없이 효율적으로 개발하실 수 있거든요... ㅎ

 

오늘 포스팅은 여기까지 작성하고 다음 포스팅에서 뵙겠습니다 ㅎㅎ

+ Recent posts