다음 사이트를 참고하여 셋팅함

https://docs.microsoft.com/ko-kr/azure/store-sendgrid-java-how-to-send-email

 

SendGrid 메일 서비스를 사용하는 방법(Java)

Azure에서 SendGrid 메일 서비스를 사용하여 메일을 보내는 방법을 알아봅니다. 코드 샘플은 Java로 작성되었습니다.

docs.microsoft.com

 

처음엔 다음과 같이 다른 SMTP 제공 사이트과 동일하게 UserId, PWD를 이용해 시도해보았으나, 오류가 발생했습니다.

private static final String SMTP_AUTH_USER = "[Sandgrid 로그인 아이디]";
private static final String SMTP_AUTH_PWD = "[Sandgrid 로그인 비밀번호]";

<오류내용>

535 Authentication failed: Basic authentication is not allowed with 2FA enabled. 
To fix, see 

https://sendgrid.com/docs/for-developers/sending-email/authentication/#basic-authentication

 해결방법

private static final String SMTP_AUTH_USER = "apikey"; // 
private static final String SMTP_AUTH_PWD = "[SG. 로 시작하는 API_KEY]"

로 변경해주니 정상동작했습니다.

 

private static final String SMTP_HOST_NAME = "smtp.sendgrid.net"; // 그냥 텍스트
private static final String SMTP_AUTH_USER = "apikey"; // 그냥 텍스트  
// sandgrid 사이트에서 발급받은 API_KEY (https://app.sendgrid.com/settings/api_keys)
private static final String SMTP_AUTH_PWD = "[API_KEY]"; 

private static class SMTPAuthenticator extends javax.mail.Authenticator {
  public PasswordAuthentication getPasswordAuthentication() {
    String username = SMTP_AUTH_USER;
    String password = SMTP_AUTH_PWD;
    return new PasswordAuthentication(username, password);
  }
}
    
public static boolean SendMail() throws Exception {
		String fromMail = "[보내는사람Email(Sandgrid 에서 등록한, 검증된 이메일 정보 사용)]";
		String fromName = "[보내는사람이름]";
		String toMail = "[받는사람Email]";
		String title = "제목";
		String content = "<p>안녕,</p> <p><b>테스트</b>중이다</p><p>고마워,<br>존</br></p>";
		
		// SMTP 정보 셋팅
		Properties properties = new Properties();
		properties.put("mail.transport.protocol", "smtp");
		properties.put("mail.smtp.host", SMTP_HOST_NAME);
		properties.put("mail.smtp.port", 587);
		properties.put("mail.smtp.auth", "true");

		Authenticator auth = new SMTPAuthenticator();
		Session mailSession = Session.getDefaultInstance(properties, auth);
		try {
			MimeMessage message = new MimeMessage(mailSession);
			
			// 보낸사람 (Sandgrid 에서 등록한, 검증된 이메일 정보 사용)
            InternetAddress from = new InternetAddress(fromMail, fromName, "UTF-8");
            message.setFrom(from);
            // 받는사람
			message.addRecipient(Message.RecipientType.TO, new InternetAddress(toMail));
            // 제목
			message.setSubject(title);
			message.setSentDate(new java.util.Date());

			Multipart multipart = new MimeMultipart("alternative");
            // 내용(본문)
			BodyPart part = new MimeBodyPart();
			part.setContent(content, "text/html; charset=utf-8"); // 한글 깨지지 않도록 utf-8 추가
			multipart.addBodyPart(part);
			message.setContent(multipart);
			// 발송
            Transport transport = mailSession.getTransport();
			transport.connect();
			transport.sendMessage(message, message.getAllRecipients());
			transport.close();
			return true;
		} catch (MessagingException ex){
			System.out.println("메일 발송 에러 : " + ex);
		}
		return false;
	}

 

 

https://sendgrid.com/docs/for-developers/sending-email/authentication/#basic-authentication

 

Authentication

Authenticating with the SendGrid API.

sendgrid.com

 

Sendgrid 메일을 JAVA에서 적용하는 경우,

401 오류 : The provided authorization grant is invalid, expired, or revoked 오류는,

{"errors":[{"message":"The provided authorization grant is invalid, expired, or revoked"
,"field":null,"help":null}]}
{Strict-Transport-Security=max-age=600; includeSubDomains
, Server=nginx, Access-Control-Allow-Origin=https://sendgrid.api-docs.io,
Access-Control-Allow-Methods=POST, Connection=keep-alive
, X-No-CORS-Reason=https://sendgrid.com/docs/Classroom/Basics/API/cors.html, 
Content-Length=116, Access-Control-Max-Age=600, Date=Mon, 17 May 2021 07:42:51 GMT
, Access-Control-Allow-Headers=Authorization, 
Content-Type, On-behalf-of, x-sg-elas-acl, Content-Type=application/json}

SendGrid sg = new SendGrid(System.getenv("[API_KEY]"));

로 제공된 부분에 System.getenv("[API_KEY]") 에서 null을 반환하여 오류가 발생합니다. 

System.getenv("") 구문을 제거 후 정상동작을 확인할 수 있습니다.

        Email from = new Email("[sendgrid에서 등록한, 검증된 보내는 사람 메일]");
		Email to = new Email("[받는사람메일]");
		String subject = "Sending with Twilio SendGrid is Fun";
		Content content = new Content("text/plain", "and easy to do anywhere, even with Java");

		Mail mail = new Mail(from, subject, to, content);
		SendGrid sg = new SendGrid("[API_KEY]");
		Request request = new Request();
		try {
			request.setMethod(Method.POST);
			request.setEndpoint("mail/send");
			request.setBody(mail.build());
			Response response = sg.api(request);
			System.out.println(response.getStatusCode());
			System.out.println(response.getBody());
			System.out.println(response.getHeaders());
		} catch (IOException ex) {
			throw ex;
		}

 

 


 

403 오류의 경우, "[sendgrid에서 등록한, 검증된 보내는 사람 메일]" 이 일치하지 않아서 발생하는 오류입니다. 

{"errors":[{"message":"The from address does not match a verified Sender Identity. 
Mail cannot be sent until this error is resolved. 
Visit https://sendgrid.com/docs/for-developers/sending-email/sender-identity/ to see the Sender Identity requirements","field":"from","help":null}]}

관리 사이트 내에서 'https://app.sendgrid.com/settings/sender_auth' 로 접근하여 이메일을 등록해주고, 해당 메일로 전송된 인증 메일을 통해 검증을 완료한 후 from 메일에 작성하여 발송테스트를 진행하면 됩니다.

아래 이미지와 같이 검증된! 마크가 있어야 완료 상태입니다.

 

API KEY 발급은 https://app.sendgrid.com/settings/api_keys 페이지로 접근하여

 

우측 API 키 생성 클릭

키 이름을 설정해주고, 전체 엑세스 [Full Access] 를 선택 

Create & View 클릭 시 바로 API키가 생성되며 다시 확인할 수 없으므로 잘 저장해두셔야 합니다. 

이 API_KEY를 이용해 메일을 발송합니다.

 

classnotfoundException이 떴다.

기존에 3.1을 부르고 있었는데 4.5.8로 변경하니까 오류가 해결됨

version 의 문제인 듯 

 

    // https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient
    compile  'org.apache.httpcomponents:httpclient:4.5.8'

 

 

SpringBoot 에서 java.io.FileNotFoundException: class path resource [com/google/common/base/Supplier.class] cannot be opened because it does not exist 오류 발생

pom.xml에 guava 를 추가해준다.

<dependency>
	<groupId>com.google.guava</groupId>
	<artifactId>guava</artifactId>
	<version>21.0</version>
</dependency>
<!-- Thanks for using https://jar-download.com -->

 

오류 내용

20210419 13:25:25.046 [restartedMain] ERROR o.s.b.SpringApplication - Application startup failed 
org.springframework.beans.factory.BeanDefinitionStoreException: Failed to process import candidates for configuration class [springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration]; nested exception is java.io.FileNotFoundException: class path resource [com/google/common/base/Supplier.class] cannot be opened because it does not exist
	at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:616)
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:299)
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245)
	at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:606)
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:299)
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:190)
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:292)
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:198)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:167)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308)
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:272)
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:92)
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525)
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
	at ...Application.main(Application.java:14)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49)
Caused by: java.io.FileNotFoundException: class path resource [com/google/common/base/Supplier.class] cannot be opened because it does not exist
	at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:172)
	at org.springframework.core.type.classreading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:50)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:98)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.createMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:89)
	at org.springframework.boot.type.classreading.ConcurrentReferenceCachingMetadataReaderFactory.getMetadataReader(ConcurrentReferenceCachingMetadataReaderFactory.java:76)
	at org.springframework.core.type.classreading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:93)
	at org.springframework.context.annotation.ConfigurationClassParser.asSourceClass(ConfigurationClassParser.java:693)
	at org.springframework.context.annotation.ConfigurationClassParser$SourceClass.getInterfaces(ConfigurationClassParser.java:870)
	at org.springframework.context.annotation.ConfigurationClassParser.processInterfaces(ConfigurationClassParser.java:363)
	at org.springframework.context.annotation.ConfigurationClassParser.processInterfaces(ConfigurationClassParser.java:371)
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:320)
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245)
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:190)
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:292)
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245)
	at org.springframework.context.annotation.ConfigurationClassParser.processImports(ConfigurationClassParser.java:606)
	... 28 common frames omitted

Process finished with exit code 0

 

 

 

며칠 전부터 핸드폰으로 AR 사진 찍는 거 하고 싶어서 고민하는 중이었는데 마침 좋은 기회로 flutter 공부를 시작할 수 있어서 감사하다.

개인적으로는 계속 백엔드 위주로 작업했고, 프론트엔드에서 하는 화면 구성은 퍼블리셔분들이 다 해주셨다. 프론트엔드 화면 구성에 대한 부담감이 있었다. 그 1px의 오차를 발견할 수 없는 타고난 무덤덤 공대생이라 엄두도 낼 수 없었는데 시작이 반이라는 마음으로 시작하게 됐다. 

예전에는 이클립스 하나 압축 푸는데도 3시간씩 걸리고 버벅 거렸던 것 같은데 어제 밤 11시 쯤 시작한 것 치고 1시쯤 프로젝트 생성 및 초기 프로젝트 실행까지 해낸게 내심 신기하다. 맨날 제자리거름 같아도 뭔가 늘긴 늘었던 4년의 시간이었나보다. 기특해 나란 녀석. 

flutter를 시작하고 기본은 회사 프로젝트로 기틀을 잡고, ARCore 공부도 하고, 6개월 후에는 ARkit도 공부해보고 싶다. 평소에 하고 싶은게 없는 사람인데 오랜만에 흥미로운 작업을 시작하게 된 것 같아 기분이 뿌듯하다.

아 회사에서 하는 프로젝트 몇 개 하고 나면 flutter 개발자로 이직할 수 있으려나. 기대되네~ 

 

안드로이드 스튜디오에서 우측 상단에 핸드폰+안드로이드 가 그려진 아이콘을 클릭.

 

이렇게 Virtual Device를 추가할 수 있는 화면이 나옵니다.

Create Virtual Device 클릭.

 

잘 몰라서 그냥 기본으로 선택되어 있는 'Pixel2' 를 선택할게요~

 

안드로이드 버전은 Q버전으로 하겠습니다. 다운로드! Download.

 

Q 우측의 Download를 누르면 아래처럼 다운로드를 해와요!

설치 완료. Finish.

 

다시 이전 창으로 돌아가서 Q 선택 후 Next.

 

Finish.

 

하면 아래처럼 Virtual Device 가 추가된 것을 확인할 수 있습니다!

Pixel 2 API 29 우측의 재생 버튼을 클릭하면 안드로이드 에뮬레이터가 실행됩니다. 

 

 

에뮬레이터를 실행하면 안드로이드 중앙 상단에 Android SDK built for x86 (mobile) 이 추가된 것을 확인할 수 있습니다.
우측 재생 버튼을 누르면 Running. 실행됩니다. 

 

하단 파란색 + 버튼을 클릭하면 푸쉬한 만큼 숫자가 증가하는 것을 확인할 수 있습니다. 

 

고생하셨습니다~ 다음엔 뭘 해야되나. 고민을 좀 해봐야겠네요~

 

 

 

프로젝트를 생성해봅니다. 두근두근.

Create New Flutter Project. 

 

Flutter Application. 선택 후 Next.

 

Project name : 프로젝트 이름
Flutter SDK path : (~\flutter\bin) 설정해줬던 그 flutter 경로로 설정하면 됩니다. (참고:hea1peak.tistory.com/216)

 

flutter 시작하기 (flutter 설치/SDK 환경변수 Path 설정/flutter doctor)

플러터? 플루터? 시작하기 웹 개발을 한 지 3년이 넘었다. 이제 이 회사에서 하는 웹 프로젝트는 거의 거기서 거기인 것 같다. 이번에 회사에서 플루터로 앱 개발을 하게 되는데 백엔드 및 API 개

hea1peak.tistory.com

Project loaction : 프로젝트 생성할 경로
Description : 설명~ 
적당히 입력하고 Next.

 

패키지명을 셋팅해주고 Finish. ( + com.new.test.flutterapp 이라고 패키지명을 했더니 new가 JRE 사용언어라 에뮬레이터를 못 띄우는 오류가 발생했다. com.test.flutterapp0 으로 변경ㅠㅠ 혹시 이 글을 보고 같은 실수가 반복되지 않길 바라며 추가합니다.)

 

프로젝트를 생성합니다.

 

프로젝트 생성 후 다음과 같이 화면이 뜨면 정상적으로 flutter 프로젝트 생성 완료.

 

다음 게시물에서는 에뮬레이터로 어플을 구동하는 부분을 셋팅해보겠습니다! AVD Manager~

 

안드로이드 스튜디오를 열면 아래 이미지처럼 초기 화면이 뜬다.

하단의 'Configure'를 클릭하여 'Plugins' 클릭.

Plugins에서 flutter를 검색하고 install 버튼을 눌러 설치.

 

동의 화면이 나오면 Accept.

 

Accept 후 Flutter를 쓰려면 Dart 가 필요합니다~
Dart도 함께 설치하겠습니까? 넵! Install.

 

설치 완료되면 'Restart IDE' 안드로이드 스튜디오를 재시작하십시오.

 

끄기 전에 Dart를 보면 이렇게 잘 설치되어 'Restart IDE' 가 동일하게 뜨는 것을 확인할 수 있습니다.

 

Restart IDE 버튼 클릭 -> Restart.

 

안드로이드 스튜디오에서 flutter 개발 환경 구성이 끝난 것 같네요! 

고생하셨습니다~ 

다음 시간에는 flutter 프로젝트를 생성해보겠어요!


E:\02_flutter\flutter>flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel stable, 2.0.4, on Microsoft Windows [Version 10.0.17134.1967], locale ko-KR)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
    X Android licenses not accepted.  To resolve this, run: flutter doctor --android-licenses
[√] Chrome - develop for the web
[√] Android Studio (version 4.1.0)
[√] Connected device (2 available)

flutter doctor --android-licenses 실행하고 라이센스 동의를 위해 모두 y + Enter. 

모두 y 완료되면 

All SDK package licenses accepted. 완료.

이전에 1개 남았던 이슈가 모두 해결되었습니다~ 

 

안드로이드 스튜디오가 노트북에서 돌아가려나.. 넘 무거운 것..

developer.android.com/studio

 

Download Android Studio and SDK tools  |  Android 스튜디오

developer.android.com

 

사이트에 들어가서 다운로드를 받습니다. DOWNLOAD ANDORID STUDIO.

 

다운로드 받은 파일을 실행. Next.

Next.

Next.

Install.

Next.

Finish. 

안드로이드 스튜디오 설치 완료!


안드로이드 스튜디오를 실행합니다.

안드로이드 스튜디오 기존 셋팅이 없기 때문에 'Do not import settings' 선택 후 OK.

구글이랑 공유할 거냐. 아니. Don't send.

Welcome 인사. Next.

Standard 선택. Next.

 

취향에 따라 모드 선택 후 Next. (저는 Light 를 사용)

 

SDK 설치 폴더 + JDK 경로 등을 알려줍니다. 이대로 설치~ Finish.

 

설치를 진행합니다.

Finish.

실행 후 설치 완료!


 

이전 게시물에서 2개였던 이슈가 1개로 줄었습니다~ 기쁜 소식! 

다음 게시물에서는 마지막 이슈를 해결해보겠습니다!

플러터? 플루터? 시작하기

웹 개발을 한 지 3년이 넘었다. 이제 이 회사에서 하는 웹 프로젝트는 거의 거기서 거기인 것 같다. 
이번에 회사에서 플루터로 앱 개발을 하게 되는데 백엔드 및 API 개발을 맡게 되었다.
앱개발자는 따로 있지만 공부용으로 그 개발에 참여하려고 한다. 아직 개발 시작도 하지 않아서 그램으로 개발을 하려고 하는데 그램이 안드로이드 스튜디오를 감당할 수 있을지 걱정이다. 우선 6개월정도 하고 올해 9월쯤 M1? M2? 맥북 나오면 구매해야지! 그 때까지 화이팅~


 

1. Flutter SDK 설치 (For. 윈도우) 

아래 링크로 들어가서 자신의 OS와 맞는 설치 파일을 다운로드!
flutter-ko.dev/docs/get-started/install/windows

 

윈도우에서 설치

 

flutter-ko.dev

윈도우/맥/리눅스 가 있다. 나는 윈도우 선택!

 

Flutter SDK 다운로드에 있는 최신 릴리즈를 다운로드 받는다. 

 

시스템 요구 사항에 다음과 같은 요구사항이 있다.

 

  • 운영 체제: 윈도우7 SP1 이상 (64-bit)
  • 저장 공간: 400 MB (IDE나 개발 도구 용량은 별도).
  • 도구: Flutter는 윈도우 환경에서 아래 도구가 필요합니다.
    • 윈도우 파워셸 5.0 또는 그 이상 버전 (윈도우10에 내장되어 있음)
    • Git for Windows 2.x, 설치하실 때, Use Git from the Windows Command Prompt 옵션을 설정해주세요.
    • 윈도우용 Git이 이미 설치되어 있다면, git 명령을 명령 프롬프트나 파워셸에서 실행되는지 확인하세요.

운영체제와 저장공간은 되었는데 도구에 대해서는.. Git for Window가 없음. 될지 안될지 모르지만 우선 스킵하고 진행.

 

다운로드 후 원하는 경로에 zip 압축 파일을 푼다. 

 

 

설치 완료!


2. 환경변수 Path 설정! 

윈도우메뉴 버튼을 누르고 '시스템' 을 검색하면 하단 이미지와 같이 시스템 환경 변수 편집이 나온다. 클릭.

 

 

환경 변수 클릭

 

Path를 선택하고 편집

새로만들기 - 압축파일을 푼 경로 (~\flutter\bin) 입력 - 확인 

환경 변수 Path 설정 완료!

 


3. flutter doctor 로 설치 확인

압축을 푼 경로의 flutter를 보면  flutter_console.bat 파일이 있는데 이 파일을 연다.

 

다은과 같은 콘솔창이 열린다.

 

명령어 flutter doctor 입력

위와 같은 이슈가 나온다.

Flutter는 2.0.4 버전으로 정상적으로 설치 완료!

다음편에서는 안드로이드 스튜디오를 설치해보겠습니다~

미래의 나를 위한 블로그 취합본.

 

STS Spring Boot Gradle 프로젝트 생성 : blog.naver.com/PostView.nhn?blogId=mering_k&logNo=221530841886&redirect=Dlog&widgetTypeCall=true&directAccess=false

 

[AWS, 웹 프로젝트] 3. STS에서 Gradle Project 생성하기

이 번 프로젝트 시작하면서 Spring Tool Suite(STS) 를 이용하게 되었다. 프로젝트를 생성하고 빌드...

blog.naver.com

STS Spring Boot Gradle 프로젝트 -> IntelliJ에서 불러오기 : meaownworld.tistory.com/13

 

eclipse Web project를 intellij로 가져오기

단순 실수로 인해 오전 내내 삽질한 것을 이리 뒤집고 저리 뒤집고 하다가 해결해서 기록한다 중간에 프로젝트가 꺼져서 다른 프로젝트로 교체도 햇으나 흐름은 같다. 먼저 그냥이클립스 프로

meaownworld.tistory.com

톰캣 

 

IntellJ -> org.junit.Jupiter.api 오류 : 25jay-study-blog.tistory.com/10

 

[스프링오류 해결] error: package org.junit.jupiter.api does not exist import org.junit (IntelliJ & gradle 로 Junit Test

1. 오류상황 다음과 같이 SpringBoot의 Junit Test가 인텔리제이에서 오류가 발생했다. 이런 경우 인텔리제이의 설정을 살펴야 한다. 2. 해결 Settings > Build, Excution, Deployment > Build Tools > Gradle에..

25jay-study-blog.tistory.com


STS 한글 깨짐 : thingsthis.tistory.com/328

 

[IntelliJ] 콘솔 한글깨짐 처리 (console log encoding .. with tomcat)

IntelliJ 에서 프로젝트 생성 및 Tomcat 을 이용한 서버 시작 시.. console 로그에서 한글이 깨지는 현상이 확인되었다. 웹상 많이 검색되는 2가지 방법과 내가 해결한 다른 1가지 방법, 총 3가지 방법에

thingsthis.tistory.com

Project 로그인 화면 (user/콘솔비밀번호) : copycoding.tistory.com/277

 

[Spring Boot] Security 사용 방법 (STS 4.5.1)

Spring Boot를 이용하여 security를 적용하는 방법을 연습해 봅니다. 먼저 프로젝트를 생성해야 테스트를 진행 하겠죠. 상단 메뉴에서 File > New > Spring Starter Project를 이용하여 프로젝트를 생성해도 됩

copycoding.tistory.com

 


오늘도 미래의 저를 위해 끄적여봅니다.
인간은 왜 같은 실수를 반복하고, 같은 오류를 창출하는가..

오늘은 프로젝트를 마무리하고 산출물 작업 중 ERD/테이블 명세서를 작성해야해서
오랜만에 ERMaster를 열었는데 한글이 안 되는 거임.. 너무 슬펐죠..

한국어지원하는 ERMaster-NHit 을 찾아 설치하려고 하니 2가지 문제에 부딪히게 됩니다. 

먼저 http://justinkwony.github.io 에서 제공해주는 내용을 따라 진행해봅니다. 

Install
Eclipse Menu -> Help -> Install New Software... -> Work with : [type Update_site_url or select zip_file]
or extract zip_file to eclipse directory.

더보기

========================================================================

(2019.09.06)
원 제작자가 sourceforge(https://sourceforge.net/projects/ermaster)를 통해 한글 지원 버전을 배포하고 있습니다.
그런데, 국산DBMS(Tibero, CUBRID) 지원 부분은 하다만듯 합니다. class 파일을 제외한 프로퍼티 류의 소스만 일부 반영되어 있어 전체소스를 github에 공개합니다.
Tibero, CUBRID 지원과 한글 테이블정의서(xls) 포함되었습니다.
http://justinkwony.github.io
https://github.com/justinkwony/ermaster-nhit

(2014.04.15)
Open Source ERD도구인 ERMaster를 한글화 및 국산DBMS(Tibero, CUBRID) 지원 기능 추가

* 변경사항
Table 편집시 인덱스 컬럼 중복 생성됨 수정
Table Edit Dialog에서 Index Tab의 구분자를 일련번호에서 인덱스명으로 변경
Outline window에서 Index Node의 인덱스 수정시 Table Node의 Table/Index 반영 안됨 수정

* Known Bugs/Issues
Tibero
- 발견하시면 Report해주세요.
CUBRID
- Schema 개념 없음
- Context Menu/가져오기/데이터베이스 : Auto Increment Column의 Seed, Increment 값을 가져오지 못함
- Context Menu/가져오기/데이터베이스 : Trigger Source(SQL) 가져오지 못함(소스 보는 방법 아시는 분 알려주세요)

The purpose of this site is to distribute ERMaster, includes Korean and Tibero, CUBRID Database support.

ERMaster is ER-Diagram editor(Eclipse Plug-in). ER-Win alternative.

Korean version
Eclipse Plug-in Update site : http://justinkwony.github.io/ermaster-nhit/update-site/
Download zip : org.insightech.er_1.0.0.v20150619-0219-nhit.zip
 
Original site
URL : http://ermaster.sourceforge.net , http://sourceforge.net/project/ermaster
Eclipse Plug-in Update site : http://ermaster.sourceforge.net/update-site -> http://sourceforge.net/project/ermaster/files/ermaster

Install
Eclipse Menu -> Help -> Install New Software... -> Work with : [type Update_site_url or select zip_file]
or extract zip_file to eclipse directory.

========================================================================

 

1. All Items are installed. 오류
    -  이미 깔려있어서 안되는거니까 uninstall 해주었습니다.
 

 

[eclipse에 설치된 소프트웨어 삭제하는 법]
 - Install New Software... -> 하단에 보면 What is already installed? 클릭


 - 삭제하려는 소프트웨어 선택 -> 하단 Uninstall 클릭

 - Finish 클릭 

- 삭제 완료~ Restart Now 합니다!

재시작하고 다시 호출했을 때 아래 이미지처럼 뜨면 Next-Next 해서 설치하면 됩니다. 

 

2. There are ne categorized Items 오류

그렇지만 저는 아래 이미지처럼 There are ne categorized Items 라고 뜨고 위 이미지처럼 나오지 않아...

하단 체크박스 중 Group Items by category 체크를 해지해주면 정상적으로 ERMaster-NHIT 을 체크하여 설치할 수 있습니다!

이제 Next-Next-동의체크-Finish 하면 설치 완료~

 

미래의 나는 또 같은 실수를 반복하겠지..

 

개발을 하다보면 회원가입 약관동의 페이지 작업을 할 때 체크박스 관련 이벤트를 주는 경우가 있다.

그 때마다 이런 저런 스크립트를 찾아 조합해서 사용하고는 했는데
이번에 작업한 내용을 블로그에 작성해본다.

다음과 같이 name="checkTmp"를 가진 3개의 체크박스가 있고,
전체선택을 위한 id="checkAll" 값을 가진 전체선택 체크박스가 있다고 하자.
최하단 버튼은 페이지 호출 시 비활성화 상태, 모두 동의한 이후에 활성화하여 다음화면으로 진행할 수 있도록 한다.

<input type="checkbox" name="checkTmp" id="checkbox1" value="Y" /> checkbox1
<input type="checkbox" name="checkTmp" id="checkbox2" value="Y" /> checkbox2
<input type="checkbox" name="checkTmp" id="checkbox3" value="Y" /> checkbox3 
        
<input type="checkbox" id="checkAll"> 전체 선택
        
<div>
	<button type="button"id="next" disabled onclick="fnSubmit();">Next</button>
</div>

 

#checkAll 체크박스가 변경되는 경우, checkAll의 체크여부를 확인하여
name=checkTmp를 가진 체크박스를 동일한 상태로 변경처리 해준다.

// 전체 선택에 따른 하위 체크박스(checkTmp)의 활성/비활성화 여부 
$('#checkAll').change(function () {
	var checked = $(this).prop('checked');
	$('input[name="checkTmp"]').prop('checked', checked);
});

 

name="checkTmp"를 가진 3개의 체크박스 중 하나가 변경되는 경우에는 반대로 변경처리가 필요하다.
checkTmp의 갯수와 선택된 checkTmp의 갯수가 같은지 비교하여
같으면 true, 다르면 false 이므로 해당 값을 기준으로 #checkAll 체크박스의 상태를 변경해준다.
$('#checkAll').prop('checked', selectAll); 구문을 처리!
#checkAll 체크박스가 동의처리된 경우에만 #next 버튼이 활성화되도록 해준다.

$('input[name="checkTmp"]').change(function () {
	var tmpLength = $('input[name="checkTmp"]').length;
	var checkedLength = $('input[name="checkTmp"]:checked').length;
	var selectAll = (tmpLength == checkedLength);
	$('#checkAll').prop('checked', selectAll);
	selectAll ? $('#next').removeAttr('disabled'):$('#next').attr('disabled','disabled');
});

 

#checkAll 체크박스가 변경되는 경우, checkAll의 체크여부를 확인하여
#checkAll 체크박스가 동의처리된 경우에만 #next 버튼이 활성화되도록 해준다.

// 전체선택 checkbox의 상태에 따라 id = next 값을 가진 버튼의 비활성화를 적용/해제
$('#checkAll').change(function () {
	// #checkAll 의 값이 true 인 경우 $('#next').removeAttr('disabled')
	// #checkAll 의 값이 false 인 경우 $('#next').attr('disabled','disabled'); 이 적용됨.
	$(this).prop('checked') ? $('#next').removeAttr('disabled'):$('#next').attr('disabled','disabled');
});     

 

 

안녕하세요 오늘부터 리눅스마스터 1급 공부를 시작하려고 글을 씁니다-

이제 1차 시험이 12일 남았습니다- 건승하시길!

 

저는 유튜브에 있는 이기적 리눅스마스터 1급 영상을 보면서 시험을 준비할 생각입니다.

먼저 큰 그림을 파악하기 위해 인터넷 서점에 공개된 리눅스마스터1급 책을 찾아보았습니다.

리눅스마스터 1급은 크게 3파트의 주제로 나누어져 있고 이 외에 기출문제가 2파트가 있습니다.
1. 리눅스 실무의 이해 / 2. 리눅스 시스템 관리 / 3. 네트워크 및 서비스의 활용

각 파트의 하위로는 중분류가 있습니다.

1. 리눅스 실무의 이해
 1) 리눅스의 개요  2) 리눅스 시스템의 이해  3) 네트워크의 이해

2. 리눅스 시스템 관리
 1) 일반 운영 관리  2) 장치 관리  3) 시스템 보안 및 관리

3. 네트워크 및 서비스의 활용
 1) 네트워크 서비스  2) 네트워크 보안 

중분류 하위에 많은 소분류가 있습니다.

대체적으로 리눅스, 시스템, 네트워크 관련된 내용일 것 같네요.

대학 졸업 이후로 리눅스를 더 많이 사용하게 됐지만 이론적으로 이해하고 접근, 사용하기 보다 때마다 필요한 명령어만 구글에 검색해서 사용했어서 자격증 시험을 잘 볼 수 있을지 염려됩니다.

 

+) 유튜브를 보면서 공부를 한 후에 기출문제를 풀어보려고 했는데 유튜브 몇 개 보고 문제 한 번 보니 무슨 말인지 도통 모르겠고, 외워야할 게 뭔지 구분이 되지 않아서 멍청해지는 기분이 듭니다. 그냥 기출문제 답을 달달 외우고 유튜브를 보면서 이해해야겠어요. 

 

+ Recent posts