1월 31, 2024

Google 블로그에서 코드블럭 prettyprint 사용하는 방법

코드블럭으로 글을 작성하면 자동으로 코드 하이라이트 기능이 적용되는 티스토리와 달리 구글 블로그는 코드 블럭 기능을 별도로 제공하고 있지 않아 코드를 작성할 때 불편함이 있다. 


오늘은 구글 블로그에서 코드블럭과 동일한 효과를 낼 수 있도록 글을 작성하는 방법을 알아보도록 하겠다. 

결론부터 말하면, 이미 소스로 만들어진 prettifier, prettyprint class를 사용할 것이다. 


1. Blogger 사이트의 테마로 들어간 뒤 HTML 수정


다음으로 맞춤설정 버튼 클릭 이후 "HTML 편집" 을 클릭해준다. 


2. </head> 태그 위 script tag 추가

HTML 편집을 클릭하면 HTML로 구성되어 있는 것을 발견할 수 있다. 


여기서 Control F (검색) 를 눌러 </head>를 검색해보자. 

HTML을 몰라도 가능하며, 혹시 궁금하신 분들을 위해 설명하자면 HTML에는 head, body 등의 tag들이 있는데 head 태그의 마지막 부분이라는 것이다. 


</head>를 검색하면 하나가 검색이 될 텐데, 그 검색된 위치 바로 윗줄에 

 <script src='https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_prettify.js'/>


위와 같이 코드를 추가해주자. 


위와 같이 작성을 해주었다면 우측 상단에 저장 버튼을 눌러준다. 


위와 같이 설정을 끝냈다면 블로그 전체로 세팅하는 부분은 끝난 것이다. 

이제 각 포스팅을 쓸 때마다 코드 블럭에만 prettyprint class를 적용시켜주면 된다. 


3. 각 블로그 글마다 HTML로 변경하여 prettyprint class 추가해주기


예시를 위해 Java Code 중 

public static void main(String[] args) throws Exception {
}

를 코드 블럭으로 넣고 싶다고 가정해보자. 


그러면 쓰고 있는 글 제목 아래쪽에 연필 모양으로 보이는 것을 클릭해보자.

클릭

그런 다음 HTML 보기를 클릭해준다.

public static void main (String[] args) throws Exception{

이라는 코드를 찾아보자. 



검색을 하면 쉽게 찾을 수 있는데 

이제 해당 코드 앞 뒤에 간단한 태그만 붙여주면 끝이다. 

코드의 앞쪽에는 
<pre class="prettyprint">

코드가 끝난 뒤쪽에는 </pre>를 붙여주면 끝이다. 


public static void main (String[] args) throws Exception{}




이런식으로 pre tag를 앞뒤로 붙여주면 

위처럼 코드블럭의 효과처럼 보이게 된다. 

public static void main 과 같은 keyword가 별도의 색깔로 표시되어 가독성이 더 좋아지는 것을 알 수 있다. 

글을 쓰다가 어떻게 보이는지 궁금하면 상단의 미리보기를 클릭하면 게시 후에 어떻게 보이는지 미리 볼 수 있다. 

HTML로 작성을 해야 하다 보니 조금 불편한 점이 있을 수 있지만 그래도 어려운 방법이 아니니 

특히나 개발 블로그를 하는 분들께 강추하는 코드블럭 사용 방법이다. 


1월 31, 2024

Front Controller Pattern의 정의와 DispatcherServlet을 사용한 예제 코드

1. Front Controller Pattern (프런트 컨트롤러 패턴) 이란? 

Front Controller Pattern (프런트 컨트롤러 패턴)이란 모든 요청을 단일 Handler에서 처리하는 패턴을 의미한다. 

Spring Web MVC 프레임워크에서는 DispatherServlet이 프런트 컨트롤러 역할을 한다.  


2. Front Controller Pattern 다이어그램




Front Controller Pattern을 사용하여 클라이언트의 요청을 받아들이고, 각 요청에 대한 적절한 Controller를 찾아 호출해주는 패턴을 구축할 수 있다. 


프런트 컨트롤러 패턴을 구축한 예제 코드는 아래와 같이 작성해볼 수 있다. 


3. DispatcherServlet을 사용한 예제코드

import org.example.mvc.controller.Controller;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/")
public class DispatcherServlet extends HttpServlet {
    private RequestMapping requestMapping;

@Override
public void init() throws ServletException {
requestMapping = new RequestMapping();
requestMapping.init();
}

@Override
protected void service(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {

try {
            // requestMapping을 통해 URI에 해당하는 Controller를 찾아줌
Controller handler = requestMapping.findHandler(request.getRequestURI());
String viewName= handler.handleRequest(request, response);
  RequestDispatcher requestDispatcher = request.getRequestDispatcher(viewName);
requestDispatcher.forward(request, response);
} catch (Exception e) {
throw new ServletException(e);
}
}
}


즉 DispatcherServlet은 HttpServlet을 extend 하고 있는 class이며 

특정 URI가 들어왔을 경우 그것에 맞는 Controller를 찾아주는 RequestMapping이라는 별도의 class가 있다고 가정했을 때 그것에 맞는 Controller가 return된다. 


해당 Controller를 통해서 들어온 요청을 처리하고 Controller에서는 view 를 return해준다. 


이렇게 DispatcherServlet을 프런트 컨트롤러로 삼아서 단일 handler에서 처리되는 패턴을 프런트 컨트롤러 패턴이라고 부른다. 


1월 30, 2024

[AI폰] 갤S24 31일 출시 소식, AI 지원기능 총정리, 할인

 


일명 AI폰이라고 불리는 갤 S24가 2024년 1월 31일 출시된다. 사전 판매로만 무려 121만대가 팔렸다고 한다. 

출시 전부터 AI폰 이라고 불릴 만큼 이전 모델 대비하여 혁신적인 기능들이 추가가 되었다고 한다. 다음은 갤 S24에서 새롭게 지원되는 신기능들이다. 

1. 갤 S24에서 새롭게 지원되는 신기능

1) 전화 통화 중 실시간 음성 번역 "Live Translate" 

무려 13개국 언어 (중국어, 영어, 불어, 독일어, 힌두어, 이탈리아어, 일본어, 한국어, 폴란드어, 포르투갈어, 태국어, 스페인어, 베트남어) 의 오디오와 텍스트 번역을 지원해주어 이 언어를 사용하는 사람과의 언어 장벽 없는 전화 통화가 가능해졌다. 

2) Personal Interpreter

스마트폰을 가운데 두고 대화하면서 서로의 말이 가운데에서 실시간으로 번역되고, 화면에 표시되며 음성까지 들을 수 있는 Personal Interpreter의 기능이 추가되었다. 

3) Android Auto

운전자의 편의를 도와주는 운전 중 여러 편의 기능들이 등장하였다. Android Auto를 사용하여 채팅 메세지를 요약해주고, 답장을 자동으로 제안해주는 등 운전자의 편의를 고려한 여러 기능들이 출시되었다. 

4) AI Chate Assistant

채팅 도중 다른 언어로 실시간으로 번역을 해줄 수 있는 기능을 제공한다. 언어 장벽 없이 유저들이 자유롭게 대화를 할 수 있도록 도와주는 기능이다. 

5) Native Voice Recorder

음성을 텍스트로 변환할 수 있는 기능이다. 갤 S24에는 Native Voice Recorder라는 앱이 탑재되어 있으며 이 앱을 사용하여 특정 음성을 여러 언어로 텍스트로 변환할 수 있는 기능을 제공한다. 

6) Circle To Search 

일상생활에서 쉽게 검색을 할 수 있도록, 유저가 펜이나 손으로 원을 그리거나 낙서를 하는 간단한 행동으로 검색을 쉽게 시작할 수 있다. 

7) Note Assist

삼성 노트 앱에 있는 기능으로 사용자가 작성한 노트를 효율적으로 요약, 정리할 수 있도록 도와주는 기능이다. 줄글로 작성한 노트도 더 보기 쉽게 요약 정리해준다. 

8) AI-Powered Camera

5배 광학 줌 50MP 카메라 센서가 갤럭시 S24 모델에 탑재되면서 AI 프로세싱 과정을 통해 고해상도 이미지를 만들어낸다. 또한 밤이나 저조도 환경에서도 더 향상된 카메라 능력을 선보인다. 사진 보정에서 또한 AI를 활용하여 더 향상된 보정 제안 기능을 제안한다. 

9) Generative AI

생성형 AI 기술을 활용하여 사진에서 원하지 않는 요소를 편하게 편집하고 재구성할 수 있다.

10) 삼성헬스에 접목된 AI

AI 기술은 삼성헬스에도 접목되어 사용자의 건강 및 운동습관을 면밀히 모니터링하고 개선방안을 제시한다.  


2. 할인 및 싸게 사는 방법

사전판매로만 121만대가 팔린 만큼, 어떻게 사야 조금이라도 더 저렴하게 살 수 있는가에 대하여 네티즌들의 관심이 뜨겁다. 

계산 결과에 따르면 공시지원금보다 25% 요금 할인이 더 유리하다고 한다. 통신사에서 요금 할인을 받는 것이 유리하다고 하며, 소비자들은 각 통신사의 요금제와 약정을 고려하여 합리적인 선택을 하면 된다. 요즘은 단말기만 별도로 구매하여 온라인 가입도 가능한 만큼 스마트폰을 구입하는 데도 선택폭이 다양해졌다. 

내일 정식으로 갤S24가 출시되는 만큼 전 세계의 이목이 집중된다. 


1월 29, 2024

Forward와 Redirect의 차이점, 도식화

 오늘은 프런트 컨트롤러 패턴에서 자주 쓰이는 

Forward와 Redirect의 차이점에 대해 알아보도록 하겠다.


Forward와 Redirect의 차이점을 한눈에 도식화하면 아래와 같다. 





Forward 방식:

  • 특징:

    • 서블릿에서 웹 브라우저 (즉, Client)를 거치지 않고 바로 다른 서블릿에게 요청을 하는 방식이다.
  • 서버의 자원 관점:

    • 서버 내부에서 일어나는 요청이므로 새롭게 자원을 만들지 않는다. 즉 HttpServletRequest, HttpServletResponse 객체를 새롭게 만들지 않고 공유한다.
ex) RequestDispatcher dispatcher = request.getRequestDispatcher("JSP to be forwarded")

dispatcher.forward(request, response)
  • URL 관점:

    • 최초 요청한 URL이 유지된다.
  • 새로운 객체 관점:

    • 같은 요청을 처리하는 동안 같은 객체를 사용한다.

Redirect 방식:

  • 특징:

    • 서블릿이 웹 브라우저 (즉, Client)를 다시 거쳐 다른 서블릿에게 요청을 하는 방식이다.
  • 서버의 자원 관점:

    • 클라이언트로부터 온 새로운 요청이기 때문에 새로운 HttpServletRequest, HttpServletResponse의 객체가 생성된다.
  • URL 관점:

    • 최초 요청한 URL과 다른 URL이 사용되며, HttpServletResponse 객체의 sendRedirect()를 이용한다.
  • 새로운 객체 관점:

    • 새로운 객체가 생성된다.

차이점 요약:

  • Forward:

    • URL이 변경되지 않음.
    • 같은 요청을 처리하는 동안 같은 객체를 사용.
    • dispatcher.forward
  • Redirect:

    • URL이 변경됨.
    • 새로운 요청을 처리하는 동안 새로운 객체를 사용.
    • sendRedirect()


1월 29, 2024

Java Reflection 개념과 Relection을 사용한 코드 예제, 사용 프레임워크 또는 라이브러리

 Relection은 힙 영역에 로드되어 있는 Class type의 객체를 통해 메소드, 필드, 생성자를 접근 제어자와 관계 없이 사용할 수 있도록 지원하는 API이다.


컴파일 시점이 아닌 런타임 시점에 동적으로 특정 클래스의 정보를 추출할 수 있는 프로그래밍 기법이다. 이는 실행 중에 클래스의 정보를 가져오거나, 메소드를 호출하거나, 필드의 값을 읽거나 쓰는 등의 작업을 수행할 수 있게 해줍니다.


Reflection은 일반적으로 코드의 유연성이나 일부 특별한 상황에서만 사용해야 합니다. Reflection을 사용할 때는 주의가 필요하며, 컴파일 타임에 검증되는 타입 안정성을 잃을 수 있습니다.


import java.lang.reflect.*;

public class ReflectionExample {
public static void main(String[] args) throws ClassNotFoundException,
 NoSuchMethodException, IllegalAccessException, 
InvocationTargetException, InstantiationException, NoSuchFieldException {

// 클래스 이름으로 Class 객체 얻기
Class<?> clazz = Class.forName("example.ExampleClass");

// 생성자 호출
Constructor<?> constructor = clazz.getConstructor();
Object instance = constructor.newInstance();

// 메소드 호출
Method method = clazz.getMethod("exampleMethod", String.class);
method.invoke(instance, "Reflection Test");

// 필드에 값 설정 및 읽기
Field field = clazz.getDeclaredField("exampleField");
field.setAccessible(true);
field.set(instance, "Reflection Field Value");
System.out.println(field.get(instance));
}
}

class MyClass {
private String myField;

public void myMethod(String message) {
System.out.println(message);
}
}

Reflection을 활용한 간단한 코드 예제이다.



위 코드는 Java Reflection을 사용하여 클래스를 동적으로 로드하고 생성자 호출, 메소드 호출, 필드에 값 설정 및 읽기를 수행하는 간단한 예제이다. 위 코드의 몇 가지 핵심적인 개념을 살펴보자.

  1. 1. Class.forName("example.ExampleClass"):

    • forName 메소드를 사용하여 지정된 클래스 이름에 해당하는 Class 객체를 얻고 위 코드에서는 "example.ExampleClass"라는 클래스를 동적으로 로드합니다.
  2. 2. Constructor<?> constructor = clazz.getConstructor():

    • getConstructor 메소드를 사용하여 기본 생성자에 해당하는 Constructor 객체를 얻는다.
  3. 3. Object instance = constructor.newInstance():

    • newInstance 메소드를 사용하여 생성자를 호출하여 클래스의 새 인스턴스를 생성한다.
  4. 4. Method method = clazz.getMethod("exampleMethod", String.class):

    • getMethod 메소드를 사용하여 지정된 이름과 매개변수 유형에 해당하는 메소드를 얻고 여기서는 "exampleMethod"이라는 메소드를 가져온다.
  5. 5. method.invoke(instance, "Reflection Test"):

    • invoke 메소드를 사용하여 메소드를 호출하고 매개변수를 넘겨준다. 첫 번째 매개변수는 메소드가 호출될 객체(인스턴스)이며, 나머지는 메소드에 전달될 파라미터이다.
  6. 6. Field field = clazz.getDeclaredField("exampleField"):

    • getDeclaredField 메소드를 사용하여 클래스에 선언된 필드 중에서 지정된 이름에 해당하는 Field 객체를 얻는다.
  7. 7. field.setAccessible(true):

    • setAccessible 메소드를 사용하여 private 접근 제어자를 갖는 필드에 접근할 수 있도록 설정한다.
  8. 8. field.set(instance, "Reflection Field Value"):

    • set 메소드를 사용하여 필드에 값을 설정한다.

이 코드를 실행하면 "Reflection Test"와 "Reflection Field Value"가 차례로 출력될 것이라는 것을 추측해볼 수 있다. Reflection을 사용하여 동적으로 클래스를 조작하고 메소드 및 필드에 접근할 수 있다는 간단한 예제이다.


Reflection을 사용하는 프레임워크/라이브러리:

  1. 1. Spring Framework:

    • Spring은 IoC (Inversion of Control) 컨테이너를 구현하는 데 Reflection을 활용한다. Bean 등록, 의존성 주입 등이 Reflection을 통해 동적으로 이루어집니다.
  2. 2. JUnit:

    • JUnit은 테스트 케이스를 동적으로 찾아 실행하는 데 Reflection을 사용한다. 특히 @Test 어노테이션이 붙은 메소드를 찾아내어 실행한다.
  3. 3. Hibernate:

    • Hibernate는 객체 관계 매핑 (ORM)을 구현하는데 Reflection을 사용한다. 클래스와 데이터베이스 테이블 간의 매핑 정보를 동적으로 처리할 수 있다.

특히 2번 JUnit에서 볼 수 있듯이 Reflection은 @Annotation이 붙은 메소드나 클래스 들을 동적으로 찾아낼 수 있는데, 관련 예제도 살펴보자.



import org.junit.jupiter.api.Test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface MyCustomAnnotation {
}

@MyCustomAnnotation
class AnnotatedClass1 {
}

@MyCustomAnnotation
class AnnotatedClass2 {
}

class NotAnnotatedClass {
}

public class AnnotationTestClass {

@Test
public void findAnnotatedClasses() {
// 패키지명 설정
String packageName = "package.org";

// 패키지 내 모든 클래스를 가져오기
Reflections reflections = new Reflections(packageName);
Set<Class<?>> classes = reflections.getTypesAnnotatedWith(MyCustomAnnotation.class);

// 결과 출력
for (Class<?> clazz : classes) {
System.out.println("Find every class with annotation: " + clazz.getName());
}
}
}

위 코드처럼 작성을 하면
package.org 라는 package 경로 아래 MyCustomAnnotation이라는 Annotation이 붙어있는 모든 class를 찾을 수 있다.

@MyCustomAnnotation이 붙은 Class는
AnnotatedClass1과 AnnotatedClass2이므로

콘솔에 출력된 로그는 아래와 같을 것이다.
Find every class with annotation: package.org.AnnotatedClass1
Find every
class with annotation: package.org.AnnotatedClass2.AnnotatedClass2

이런 식으로 오늘은 Reflection을 사용한 코드 예제들을 알아보았다.