티스토리 뷰

Backend/Java

처음 만난 SparkJava

ellie.strong 2022. 4. 3. 14:48
728x90

우아한테크코스의 체스 미션에서는 SparkJava를 활용해 웹 UI를 적용해야한다. 이를 위한 캡틴 포비의 강의가 제공되며, 해당 강의를 들으며 학습한 내용을 정리했다.

 

  • 프로젝트 생성 및 세팅
  • 클라이언트 요청 처리 : GET & POST
  • Template Engine : Handlebars
  • Java Bean을 이용한 데이터 전송

프로젝트 생성

IntelliJ에서 SpringBoot 프로젝트 생성 기능을 이용해 일단 프로젝트를 생성한다.

build.gradle에서 SpringBoot와 관련된 설정들을 제거하고, main, test 디렉토리의 초기 파일들을 모두 제거한다.

plugins {
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

dependencies {

}

tasks.named('test') {
    useJUnitPlatform()
}

 

클라이언트 요청 처리(응답)

build.gradle에 dependency를 추가하면, spark를 사용하기 위해 필요한 라이브러리들을 자동으로 다운받을 수 있다.

 

Gradle 7.0 이상

dependencies {
    implementation("com.sparkjava:spark-core:2.9.3")
}

Gradle 7.0 이전

dependencies {
    compile "com.sparkjava:spark-core:2.9.3"
}

 

프로젝트 실행

Spark Framework Documentation에는 spark를 쉽게 시작하는 방법과 제공하는 기능들에 대한 설명을 제공한다.

GET

간단한 코드 작성을 통해 "localhost:4567/hello"로 들어오는 요청을 처리하는 웹 페이지를 만들어볼 수 있다.

✅  브라우저는 기본적으로 get 방식을 이용해 서버에 요청을 보낸다.

public class HelloWorld {
    public static void main(String[] args) {
        get("/hello", (req, res) -> "Hello World");
    }
}

":name"과 같은 파라미터의 이름을 이용해 동적으로 변경되는 데이터를 받아올 수 있다.

get("/hello/:name", (req, res) -> {
    return "Hello : " + req.params(":name");
});

query string을 이용해 데이터를 넘기는 경우 queryParams() 메서드를 이용할 수 있다.

✅  Query String : url 주소에 미리 협의된 형식을 이용해 데이터를 파라미터를 통해 넘기는 것을 말한다.

get("/hello", (req, res) -> {
    return "Hello : " + req.queryParams("age") + "살 " + req.queryParams("name");
});

POST

클라이언트에서 post 방식으로 보낸 요청을 처리할 수 있다. 

post("/hello", (req, res) -> {
    return "POST Hello : " + req.queryParams("age") + "살 " + req.queryParams("name");
});
<form action="/hello" method="post">
    이름 : <input type="text" name="name"/>
    <br/>
    <br/>
    나이 : <input type="text" name="age"/>
    <br/>
    <br/>
    <input type="submit" value="회원가입"/>
</form>

✅  html과 같은 정적(static) 파일의 저장 경로를 지정해서 사용할 수 있다. (기본 : main/resources)

staticFiles.location("/static");

 

Template Engine

동적인 페이지를 구현하게 해준다. 

✅  동적인 페이지 : 서버에서 클라이언트로 보낸 데이터를 이용해 페이지를 구성하는 것

 

우리는 SparJava에서 제공하는 template engin들 중 HandleBars를 이용한다.

📌  SparkJava Template Engine Docs

Handlebars

dependency를 추가해 Handlebars 라이브러리를 다운받는다.

dependencies {
    implementation("com.sparkjava:spark-core:2.9.3")
    implementation("com.sparkjava:spark-template-handlebars:2.7.1") // 의존성 추가
}

Map을 이용해 JSON과 비슷한 형식으로 데이터를 저장해 넘길 수 있다. HandlebarsTemplateEngine은 render() 메서드를 이용해 데이터를 담은 Map과 동적 html을 엮어 브라우저에 렌더링해준다.

public static void main(String[] args) {
    post("/hello", (req, res) -> {
        Map<String, Object> model = new HashMap<>();
        model.put("name", req.queryParams("name"));
        model.put("age", req.queryParams("age"));

        return render(model, "result.html");
    });
}

public static String render(Map<String, Object> model, String templatePath) {
    return new HandlebarsTemplateEngine().render(new ModelAndView(model, templatePath));
}

{{name}}, {{age}}에 우리가 Map에 저장한 데이터를 넣어준다. 이것은 HandleBars의 문법을 따르며, 이는 Mustache의 문법을 기본으로 만들어졌다. (파이썬의 Template Engine Jinja가 생각난다.. 꽤 편했지..)

📌  Handlebars 공식 문서

📌  Mustache 문법

<h1>회원 가입 결과</h1>
이름 : {{name}}
<br/>
<br/>
나이 : {{age}}

주의할 점으로 해당 html은 정적 파일이 아니라 동적 파일이 되므로 동적 파일의 기본 경로인 resources/templates로 동적 html 파일을 이동시켜줘야 정삭적으로 동작한다.

 

Java Bean

자바빈은 jsp에서 객체를 가져오기 위한 기법으로, 데이터 전달 오브젝트 파일 DTO(Data Transfer Object)라고도 한다.

서버에서는 자바빈 클래스에 데이터를 담아 클라이언트로 보낼 수 있다. 이럴 경우 html 파일에서는 Handlebars 문법을 이용해 데이터에 접근할 수 있으며, 자바빈 규약을 따르기 때문에 클래스에는 getter가 존재해야 정상적으로 동작한다.

post("/users", (req, res) -> {
    User user = new User();
    user.setName(req.queryParams("name"));
    user.setAge(req.queryParams("age"));

    Map<String, Object> model = new HashMap<>();
    model.put("user", user);

    return render(model, "result.html");
});
<h1>회원 가입 결과</h1>
이름 : {{user.name}}
<br/>
<br/>
나이 : {{user.age}}
<h1>회원 가입 결과</h1>
{{#user}}
이름 : {{name}}
<br/>
<br/>
나이 : {{age}}
{{/user}}

Handlebars 내부에서 for문을 처리하므로 따로 명시할 필요 없이 List를 이용해 데이터를 보낼 수 있다. 

List<User> users = new ArrayList<>();
post("/users", (req, res) -> {
    User user = new User();
    user.setName(req.queryParams("name"));
    user.setAge(req.queryParams("age"));
    users.add(user);

    Map<String, Object> model = new HashMap<>();
    model.put("users", users);

    return render(model, "result.html");
});
<h1>회원 가입 결과</h1>
{{#users}}
이름 : {{name}}, 나이 : {{age}}
<br/>
{{/users}}
<h1>회원 가입 결과</h1>
{{#users}}
이름 : {{this.name}}, 나이 : {{this.age}}
<br/>
{{/users}}

 

 

 

 

728x90
댓글
공지사항
최근에 올라온 글