1. 개요

Blade 는 작은 Java 8+ MVC 프레임워크로, 독립적이고 생산적이며 우아하고 직관적이며 초고속이라는 몇 가지 명확한 목표를 염두에 두고 처음부터 구축되었습니다.

Node의 Express , Python의 Flask , Golang의 Macaron / Martini 등 다양한 프레임워크가 디자인에 영감을 주었습니다 .

Blade는 야심차게 더 큰 프로젝트인 Let's Blade 의 일부이기도 합니다 . 여기에는 Captcha 생성에서 JSON 변환, 템플릿에서 간단한 데이터베이스 연결에 이르기까지 다른 작은 라이브러리의 이기종 컬렉션이 포함됩니다.

그러나 이 사용방법(예제)에서는 MVC에만 중점을 둘 것입니다.

2. 시작하기

우선 비어 있는 Maven 프로젝트를 만들고 pom.xml최신 Blade MVC 의존성을 추가해 보겠습니다 .

<dependency>
    <groupId>com.bladejava</groupId>
    <artifactId>blade-mvc</artifactId>
    <version>2.0.14.RELEASE</version>
</dependency>

2.1. 블레이드 애플리케이션 번들링

우리 앱은 JAR로 생성되기 때문에 WAR처럼 /lib 폴더 가 없습니다 . 결과적으로 이것은 필요한 다른 JAR과 함께 blade-mvc JAR을 앱에 제공하는 방법에 대한 문제로 이어집니다 .

이를 수행하는 다양한 방법은 각각 장단점이 있으며 Maven 사용방법(예제)로 실행 가능한 JAR을 만드는 방법 에 설명되어 있습니다 .

간단히 하기 위해 pom.xml 에서 가져온 모든 JAR을 분해한 다음 모든 클래스를 단일 uber-JAR에 함께 묶는 Maven 어셈블리 플러그인 기술을 사용합니다 .

2.2. 블레이드 애플리케이션 실행

Blade는 놀라운 비동기 이벤트 기반 네트워크 애플리케이션 프레임워크인 Netty를 기반으로 합니다 . 따라서 블레이드 기반 애플리케이션을 실행하기 위해 외부 애플리케이션 서버나 서블릿 컨테이너가 필요하지 않습니다. JRE로 충분합니다.

java -jar target/sample-blade-app.jar

그 후에 응용 프로그램은 http://localhost:9000 URL에서 액세스할 수 있습니다.

3. 아키텍처 이해

Blade의 아키텍처는 매우 간단합니다.

건축학

항상 동일한 수명 주기를 따릅니다.

  1. Netty가 요청을 받습니다.
  2. 미들웨어가 실행됩니다(선택 사항).
  3. WebHook이 실행됩니다(선택 사항).
  4. 라우팅이 수행됩니다.
  5. 응답이 클라이언트로 전송됩니다.
  6. 대청소

다음 섹션에서 위의 기능을 살펴보겠습니다.

4. 라우팅

요컨대 MVC의 라우팅은 URL과 컨트롤러 간의 바인딩을 만드는 데 사용되는 메커니즘입니다.

블레이드는 기본 경로와 어노테이션이 있는 경로의 두 가지 유형의 경로를 제공합니다.

4.1. 기본 경로

기본 경로는 마이크로 서비스 또는 최소 웹 애플리케이션과 같은 매우 작은 소프트웨어를 위한 것입니다.

Blade.of()
  .get("/basic-routes-example", ctx -> ctx.text("GET called"))
  .post("/basic-routes-example", ctx -> ctx.text("POST called"))
  .put("/basic-routes-example", ctx -> ctx.text("PUT called"))
  .delete("/basic-routes-example", ctx -> ctx.text("DELETE called"))
  .start(App.class, args);

경로를 등록하는 데 사용되는 메서드의 이름은 요청을 전달하는 데 사용되는 HTTP 동사에 해당합니다. 저것과 같이 쉬운.

이 경우 텍스트를 반환하지만 이 사용방법(예제)의 뒷부분에서 볼 수 있듯이 페이지를 렌더링할 수도 있습니다.

4.2. 어노테이션이 달린 경로

물론 보다 현실적인 사용 사례를 위해 어노테이션을 사용하여 필요한 모든 경로를 정의할 수 있습니다. 이를 위해 별도의 클래스를 사용해야 합니다.

우선 @Path 어노테이션을 통해 컨트롤러를 생성해야 합니다. 이 컨트롤러는 시작하는 동안 Blade에 의해 스캔됩니다.

그런 다음 가로채려는 HTTP 메서드와 관련된 경로 어노테이션을 사용해야 합니다.

@Path
public class RouteExampleController {    
    
    @GetRoute("/routes-example") 
    public String get(){ 
        return "get.html"; 
    }
    
    @PostRoute("/routes-example") 
    public String post(){ 
        return "post.html"; 
    }
    
    @PutRoute("/routes-example") 
    public String put(){ 
        return "put.html"; 
    }
    
    @DeleteRoute("/routes-example") 
    public String delete(){ 
        return "delete.html"; 
    }
}

간단한 @Route 어노테이션을 사용하고 HTTP 메서드를 매개변수로 지정할 수도 있습니다 .

@Route(value="/another-route-example", method=HttpMethod.GET) 
public String anotherGet(){ 
    return "get.html" ; 
}

반면에 메서드 매개 변수를 넣지 않으면 경로는 동사에 관계없이 해당 URL에 대한 모든 HTTP 호출을 가로챕니다.

4.3. 매개변수 주입

경로에 매개변수를 전달하는 방법에는 여러 가지가 있습니다. 설명서의 몇 가지 예를 통해 살펴보겠습니다 .

  • 양식 매개변수:
@GetRoute("/home")
public void formParam(@Param String name){
    System.out.println("name: " + name);
}
  • 편안한 매개변수:
@GetRoute("/users/:uid")
public void restfulParam(@PathParam Integer uid){
    System.out.println("uid: " + uid);
}
  • 파일 업로드 매개변수:
@PostRoute("/upload")
public void fileParam(@MultipartParam FileItem fileItem){
    byte[] file = fileItem.getData();
}
  • 헤더 매개변수:
@GetRoute("/header")
public void headerParam(@HeaderParam String referer){
    System.out.println("Referer: " + referer);
}
  • 쿠키 매개변수:
@GetRoute("/cookie")
public void cookieParam(@CookieParam String myCookie){
    System.out.println("myCookie: " + myCookie);
}
  • 바디 매개변수:
@PostRoute("/bodyParam")
public void bodyParam(@BodyParam User user){
    System.out.println("user: " + user.toString());
}
  • 속성을 경로로 전송하여 호출되는 값 객체 매개변수:
@PostRoute("/voParam")
public void voParam(@Param User user){
    System.out.println("user: " + user.toString());
}
<form method="post">
    <input type="text" name="age"/>
    <input type="text" name="name"/>
</form>

5. 정적 리소스

블레이드는 필요한 경우 정적 리소스를 /resources/static 폴더 에 넣기만 하면 서비스를 제공할 수도 있습니다 .

예를 들어  src/main/resources/static/app.css는 http://localhost:9000/static/app.css 에서 사용할 수 있습니다  .

5.1. 경로 사용자 지정

프로그래밍 방식으로 하나 이상의 정적 경로를 추가하여 이 동작을 조정할 수 있습니다.

blade.addStatics("/custom-static");

src/main/resources/application.properties 파일을 편집하여 구성을 통해 동일한 결과를 얻을 수 있습니다 .

mvc.statics=/custom-static

5.2. 리소스 List 활성화

Security상의 이유로 기본적으로 꺼져 있는 기능인 정적 폴더의 콘텐츠 List을 허용할 수 있습니다.

blade.showFileList(true);

또는 구성에서:

mvc.statics.show-list=true

이제  http://localhost:9000/custom-static/을 열어 폴더의 내용을 표시할 수 있습니다.

5.3. WebJar 사용

WebJars 소개 사용방법(예제) 에서 볼 수 있듯이 JAR로 패키징된 정적 리소스도 실행 가능한 옵션입니다.

Blade는 /webjars/ 경로 아래에 자동으로 노출합니다.

예를 들어 pom.xml 에서 Bootstrap을 가져오겠습니다 .

<dependency>
    <groupId>org.webjars</groupId>
    <artifactId>bootstrap</artifactId>
    <version>4.2.1</version>
</dependency>

결과적으로 http://localhost:9000/webjars/bootstrap/4.2.1/css/bootstrap.css 에서 사용할 수 있습니다.

6. HTTP 요청

블레이드는 서블릿 사양을 기반으로 하지 않기 때문에 인터페이스 Request 및 클래스 HttpRequest 와 같은 개체는 우리가 익숙한 것과 약간 다릅니다.

6.1. 양식 매개변수

양식 매개변수를 읽을 때 Blade는 쿼리 메소드의 결과에서  Java의 Optional을 최대한 활용합니다 (아래의 모든 메소드는 Optional  객체를 반환함).

  • 쿼리(문자열 이름)
  • queryInt(문자열 이름)
  • queryLong(문자열 이름)
  • queryDouble(문자열 이름)

대체 값으로도 사용할 수 있습니다.

  • 문자열 쿼리(문자열 이름, 문자열 defaultValue)
  • int queryInt(문자열 이름, int defaultValue)
  • 긴 queryLong(문자열 이름, 긴 defaultValue)
  • double queryDouble(문자열 이름, double defaultValue)

automapped 속성을 통해 양식 매개변수를 읽을 수 있습니다.

@PostRoute("/save")
public void formParams(@Param String username){
    // ...
}

또는 요청 개체에서:

@PostRoute("/save")
public void formParams(Request request){
    String username = request.query("username", "Baeldung");
}

6.2. JSON 데이터

이제 JSON 개체를 POJO에 매핑하는 방법을 살펴보겠습니다.

curl -X POST http://localhost:9000/users -H 'Content-Type: application/json' \ 
  -d '{"name":"Baeldung","site":"baeldung.com"}'

POJO( 가독성을 위해 Lombok 으로 어노테이션 처리됨 ):

public class User {
    @Getter @Setter private String name;
    @Getter @Setter private String site;
}

다시 이 값은 주입된 속성으로 사용할 수 있습니다.

@PostRoute("/users")
public void bodyParams(@BodyParam User user){
    // ...
}

그리고 요청 에서 :

@PostRoute("/users")
public void bodyParams(Request request) {
    String bodyString = request.bodyToString();
}

6.3. RESTful 매개변수

localhost:9000/user/42 와 같은 예쁜 URL의 RESTFul 매개변수 도 일급 시민입니다.

@GetRoute("/user/:id")
public void user(@PathParam Integer id){
    // ...
}

평소와 같이 필요할 때 Request 개체 에 의존할 수 있습니다 .

@GetRoute("/user")
public void user(Request request){
    Integer id = request.pathInt("id");
}

분명히 LongString 유형 에도 동일한 방법을 사용할 수 있습니다 .

6.4. 데이터 바인딩

블레이드는 JSON 및 양식 바인딩 매개변수를 모두 지원하고 이를 모델 객체에 자동으로 연결합니다.

@PostRoute("/users")
public void bodyParams(User user){}

6.5. 요청 및 세션 속성

요청 및  세션 에서 객체를 읽고 쓰는 API는  매우 명확합니다.

키와 값을 나타내는 두 개의 매개변수가 있는 메서드는 다른 컨텍스트에 값을 저장하는 데 사용할 수 있는 뮤테이터입니다.

Session session = request.session();
request.attribute("request-val", "Some Request value");
session.attribute("session-val", 1337);

반면 키 매개변수만 받는 동일한 메서드는 접근자입니다.

String requestVal = request.attribute("request-val");
String sessionVal = session.attribute("session-val"); //It's an Integer

흥미로운 기능은 Generic 반환 유형 <T> T 로 결과를 캐스팅할 필요가 없습니다.

6.6. 헤더

반대로 요청 헤더는 요청에서만 읽을 수 있습니다.

String header1 = request.header("a-header");
String header2 = request.header("a-safe-header", "with a default value");
Map<String, String> allHeaders = request.headers();

6.7. 유용

다음 유틸리티 메서드는 기본적으로 사용할 수 있으며 추가 설명이 필요하지 않을 정도로 명확합니다.

  • 부울 isIE()
  • 부울 isAjax()
  • 문자열 콘텐츠 유형()
  • 문자열 사용자 에이전트()

6.8. 쿠키 읽기

특히 Optional<Cookie> 를 읽을 때 Request 개체가 쿠키를 처리하는 데  어떻게 도움이 되는지 살펴보겠습니다 .

Optional<Cookie> cookieRaw(String name);

쿠키가 존재하지 않는 경우 적용할 기본값을 지정하여 문자열 로 가져올 수도 있습니다  .

String cookie(String name, String defaultValue);

마지막으로 모든 쿠키를 한 번에 읽을 수 있는 방법입니다( 는 쿠키의 이름, 은 쿠키의 값).

Map<String, String> cookies = request.cookies();

7. HTTP 응답

Request 에서 수행한 것과 유사하게 라우팅 메서드의 매개 변수로 선언하기만 하면 Response 개체 에 대한 참조를 얻을 수 있습니다 .

@GetRoute("/")
public void home(Response response) {}

7.1. 간단한 출력

편리한 출력 방법 중 하나를 통해 200 HTTP 코드 및 적절한 Content-Type과 함께 간단한 출력을 호출자에게 쉽게 보낼 수 있습니다.

먼저 일반 텍스트를 보낼 수 있습니다.

response.text("Hello World!");

둘째, HTML을 생성할 수 있습니다.

response.html("<h1>Hello World!</h1>");

셋째, 마찬가지로 XML을 생성할 수 있습니다.

response.xml("<Msg>Hello World!</Msg>");

마지막으로 String을 사용하여 JSON을 출력할 수 있습니다 .

response.json("{\"The Answer\":42}");

POJO에서도 자동 JSON 변환을 활용합니다.

User user = new User("Baeldung", "baeldung.com"); 
response.json(user);

7.2. 파일 출력

서버에서 파일을 다운로드하는 것은 더 간단할 수 없습니다.

response.download("the-file.txt", "/path/to/the/file.txt");

첫 번째 매개변수는 다운로드할 파일의 이름을 설정하고 두 번째 매개변수( 여기서는 String 으로 구성된 File 객체 )는 서버에 있는 실제 파일의 경로를 나타냅니다.

7.3. 템플릿 렌더링

반응형