티스토리 뷰
우아한테크코스의 체스 미션에서는 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가 생각난다.. 꽤 편했지..)
<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}}
'Backend > Java' 카테고리의 다른 글
Spark Java에서 에러 메시지 전송하기 (0) | 2022.04.07 |
---|---|
DAO, DTO, Service, Controller (feat. 체스미션) (0) | 2022.04.06 |
공유 중인 가변 데이터는 동기화해 사용하라 (0) | 2022.03.30 |
Enum에서 상수를 사용하는 방법 (4) | 2022.03.17 |
상속은 정말 나쁜가? (0) | 2022.03.17 |