Java Spring 5 새로운 기능 기능 웹 프레임 워크
예를 들어보세요
샘플 응용 프로그램의 발췌문부터 시작하겠습니다. 아래는 개인 개체를 노출시키는 응답 정보 라이브러리입니다. 플럭스 <person>과 전통적인 반환 목록 <person>을 반환한다는 점을 제외하고는 전통적인 비 응답 정보 라이브러리와 매우 유사합니다. 모노 <void>는 완료 플래그로 사용됩니다. 저장이 완료된시기를 나타냅니다.
공개 인터페이스 개인 편견 {mono <person> getperson (int id); Flux <person> AllPeople (); 모노 <void> saveperson (mono <person> person);}다음은 새로운 기능적 웹 프레임 워크를 사용하여 라이브러리를 노출시키는 방법입니다.
routerfunction <?> route = route (get ( "/person/{id}"), request-> {mono <person> person = mono.justorempty (request.pathvariable ( "id")) . (route (get ( "/person"), request-> {flux <person> people = repository.allpeople (); return response.ok (). body (frompublisher (people, person.class);})) response.ok (). build (repository.saveperson (person));});예를 들어 Reactor Netty에서 실행하는 방법을 소개합니다.
httphandler httphandler = routerfunctions.tohttphandler (route); Reactorhttphandleradapter 어댑터 = new Reactorhttphandleradapter (httphandler); httpserver server = httpserver.create ( "localhost", 8080);
마지막으로해야 할 일은 시도해 보는 것입니다.
$ curl 'http : // localhost : 8080/person/1'{ "name": "John Doe", "Age": 42}아래에는 더 많은 소개가 있습니다. 더 깊이 파고 봅시다!
핵심 구성 요소
핵심 구성 요소 (핸들러 기능, 라우터 기능 및 필터 기능을 철저히 설명하여 프레임 워크를 소개합니다. 이 세 가지 인터페이스와 기사에 설명 된 기타 모든 유형은 org.springframework.web.reactive.functive.function 패키지에서 찾을 수 있습니다.
핸들러 기능
이 새로운 프레임 워크의 시작점은 handlerfunction <t>이며, 이는 기본적으로 함수 <request, response <t >>이며, 요청 및 응답이 새로 정의되고 변하지 않는 인터페이스는 JDK-8 DSL을 기본 HTTP 메시지에 제공하는 데 친숙합니다. 응답 엔티티를 구축하기위한 편리한 빌드 도구입니다. 응답에서 볼 수있는 것과 매우 유사합니다. 핸들러 기능 주석에 해당하는 것은 @requestmapping의 메소드입니다.
다음은 "Hello World"처리 기능의 간단한 예입니다. 200 개 상태와 문자열이있는 응답 메시지를 반환합니다.
handlerFunction <string> helloworld = request-> response.ok ().
위의 예에서 보았 듯이, 취급 함수는 원자로 기반으로 빌드하여 완전히 반응합니다. 플럭스, 모노 또는 기타 해당 스트림 게시자를 응답 유형으로 받아들입니다.
한 가지 주목할 점은 핸들러 기능 자체가 매개 변수로 취급하는 대신 응답을 반환하기 때문에 부작용이 없다는 것입니다 (Servlet.Service (ServletRequest, ServletResponse) 참조. 부작용이 없으면 많은 이점이 있습니다 : 쉽게 테스트, 쓰기 및 최적화.
라우터 기능
수신 요청은 routerfunction <t> (즉, 함수 <request, 선택적 <handlerfunction <t >>)을 사용하여 핸들러 함수로 라우팅되며 일치하면 핸들러로 라우팅됩니다. 그렇지 않으면 빈 결과가 반환됩니다. 라우팅 방법은 @requestmapping 주석과 유사하게 작동합니다. 그러나 또 다른 중요한 차이가 있습니다. 주석을 사용할 때 경로는 주석이 달린 값이 표현할 수있는 범위로 제한되며 이러한 방법의 오버레이를 처리하기가 어렵습니다. 라우팅 방법을 사용하는 경우 코드가 있으며 쉽게 덮어 쓰거나 교체 할 수 있습니다.
아래는 임베디드 처리 기능이있는 라우팅 기능의 예입니다. 조금 길지만 걱정하지 마십시오. 더 짧게 만드는 방법을 찾을 수 있습니다.
routerfunction <string> helloworldroute = request-> {if (request.path (). equals ( "/hello -world"))) {return optional.of (r-> response.ok (). } else {return optional.empty (); }};일반적으로 완전한 라우팅 방법을 작성할 필요는 없지만 RouterFunctions.route ()를 정적으로 소개하여 요청 판단 공식 (예 : 술어 <요청>) 및 handlerFunction)을 사용하여 라우팅 메소드를 생성 할 수 있습니다. 판단이 성공하면 처리 방법이 반환됩니다. 그렇지 않으면 빈 결과가 반환됩니다. 다음은 경로 방법을 사용하는 위의 예입니다.
routerfunction <string> HelloWorlDroute = routerFunctions.route (request-> request.path (). equals ( "/hello -world"), request-> response.ok (). body (fromObject ( "Hello World"));
요청 사료를 가져올 수 있습니다.* 경로, HTTP 방법, 컨텐츠 유형 등을 기반으로 일반적으로 사용되는 Predicates에 액세스하려면 helloworldroute를 더 간단하게 만들 수 있습니다.
routerfunction <string> HelloWorlDroute = routerFunctions.route (requestPredicates.path ( "/Hello -World"), request-> response.ok ().
조합 기능
두 개의 라우팅 함수는 새로운 라우팅 함수, 처리 기능으로 경로를 형성 할 수 있습니다. 첫 번째 함수가 일치하지 않으면 두 번째 기능이 실행됩니다. routerfunction. ()를 호출하여 이와 같은 두 가지 라우팅 기능을 결합 할 수 있습니다.
routerfunction <?> Route = Route (PATH ( "/hello -World"), request-> response.ok (). body (FromObject ( "Hello World"))).
경로가 /hello- 월드와 일치하면 위의 "Hello World"에 응답하고 /the-answer가 일치하는 경우 동시에 "42"가 반환됩니다. 일치하지 않으면 빈 옵션이 반환됩니다. 결합 된 라우팅 함수는 순서대로 실행되므로 특정 기능 전에 일반 기능을 넣는 것이 좋습니다.
호출 및 또는 또는 또는 또는 또는 또는 또는. 이것은 다음과 같이 작동합니다. 두 개의 주어진 Predicates 일치가 일치하는 경우 결과는 일치하며 두 경기 중 하나가 일치하는 경우 또는 일치합니다. 예를 들어:
routerfunction <?> Route = Route (메소드 (httpMethod.get). 및 (경로 ( "/hello -world"), request-> response.ok (). body (fromObject ( "hello world"))) response.ok (). body (fromobject ( "42")));
실제로, 요청 사전에서 발견되는 대부분의 선행은 결합되어 있습니다! 예를 들어, requestPredicates.get (String)은 requestPredicates.Method (httpMethod) 및 requestPredicates.path (String)의 구성입니다. 따라서 위의 코드를 다음과 같이 다시 작성할 수 있습니다.
routerfunction <?> route = route (get ( "/hello -world"), request-> response.ok (). body (fromobject ( "hello world")))
메소드 참조
그건 그렇고 : 지금까지 우리는 모든 처리 기능을 인라인 람다 표현으로 작성했습니다. 이것은 데모와 짧은 예제에서 잘 수행되지만, 두 가지 문제를 혼합하려고하기 때문에 "혼란"을 유발하는 경향이 있다고 말해야합니다. 라우팅 요청 및 요청 처리 요청. 따라서 우리는 그것이 더 간단하게 만들 수 있는지 알고 싶습니다. 먼저 처리 코드가 포함 된 클래스를 만듭니다.
클래스 데모 핸들러 {public responsk <string> helloworld (요청 요청) {return response.ok (). }/ * http://www.manongjc.com/article/1590.html */public response <string> theanswer (요청 요청) {return response.ok (). }}두 방법 모두 처리 기능과 호환되는 플래그가 있습니다. 이를 통해 메소드 참조를 사용할 수 있습니다.
데모 핸들러 핸들러 = 새로운 데모 핸들러 (); // 또는 dirouterfunction <?> 경로 = Route = Route (get ( "/hello-world"), handler :: helloworld) 및 (route (get ( "/the-answer"), handler :: theanswer);
필터 기능
라우터 기능 (filterfunction.filter)을 호출하여 라우팅 함수에 의해 매핑 된 경로는 필터링 <t, r>가 본질적으로 이중화 <request, handlerfunction <t>, 응답 <r >>입니다. 함수의 핸들러 매개 변수는 전체 체인의 다음 항목을 나타냅니다. 이것은 일반적인 핸들러 기능이지만 여러 필터가 첨부되면 다른 필터 기능이 될 수도 있습니다. 경로에 로그 필터를 추가하겠습니다.
// http : //www.manongjc.comrouterfunction <?> Route = Route = Route = Route (get ( "/hello-world"), handler :: HelloWorld) 및 (Route (get ( "/the-answer"), Handler :: theanswer) .filter ((요청, 다음)-> {handler invorat.print. 요청.다음 핸들러를 호출할지 여부는 선택 사항입니다. 이것은 보안 및 캐싱 체계에 매우 유용합니다 (예 : 사용자가 충분한 권한이있는 경우에만 다음에 호출).
경로는 무한 라우팅 기능이므로 다음 핸들러가 반환 할 응답 정보 유형을 알고 있습니다. 이것이 우리가 필터에서 응답으로 끝나고 물체와 신체에 응답하는 이유입니다. 핸들러 클래스에서 두 메서드 모두 return response <string>이므로 문자열 응답 본문을 가질 수 있어야합니다. routerfunction.andsame () 대신 및 ()를 사용 하여이 작업을 수행 할 수 있습니다. 이 조합 방법은 파라미터 라우팅 기능이 동일한 유형이어야합니다. 예를 들어, 모든 응답을 대문자로 만들 수 있습니다.
routerfunction <string> route = Route (get ( "/hello-world"), handler :: helloworld). 및 route (get ( "/the-answer"), handler :: theanswer) .filter ((요청, 다음)-> {response <string> response = next.handle (요청); 응답 (응답).주석을 사용하여 @controlleradvice 및/또는 servletfilter를 사용하여 유사한 기능을 구현할 수 있습니다.
서버를 실행하십시오
이 모든 것이 괜찮지 만 잊어 버린 한 가지 : 실제 HTTP 서버에서 이러한 기능을 어떻게 실행할 수 있습니까? 의심 할 여지없이 다른 기능을 호출함으로써 대답은 의심 할 여지가 있습니다. routerfunctions.tohttphandler ()를 사용하여 라우팅 함수를 httphandler로 변환 할 수 있습니다. Httphandler는 Spring 5.0 M1에 도입 된 응답 추상화입니다. Reactor Netty, RXnetty, Servlet 3.1+ 및 Undertow와 같은 다양한 응답 런타임에서 실행할 수 있습니다. 이 예에서는 반응기 Netty에서 경로를 실행하는 방법을 보여주었습니다. Tomcat의 경우 다음과 같습니다.
httphandler httphandler = routerfunctions.tohttphandler (route); httpservlet servlet = new servlethttphandleradapter (httphandler); tomcat server = new tomcat (); context rootcontext = server.addcontxt ( "", system.getProperty ( "java.io.tmpdir")); tomcat.addservlet (rootcontext, "servlet", servlet); rootcontext.addservletmapping ( "/", "servlet"); tomcatserver.start ();
주목할만한 점은 위의 코드가 스프링 응용 프로그램 컨텍스트에 의존하지 않는다는 것입니다. jdbctemplate 및 기타 스프링 유틸리티 클래스와 마찬가지로 응용 프로그램 컨텍스트를 사용하는 것은 선택 사항입니다. 컨텍스트에서 핸들러 및 라우팅 기능을 연결할 수 있지만 필요하지 않습니다.
또한 라우팅 함수를 핸드 레이 핑으로 변환하여 DispatcherHandler에서 실행할 수 있도록 (응답 형 @Controllers가 필요할 수 있음)에 유의하십시오.
결론적으로
간단한 요약을 통해 결론을 내겠습니다.
보다 포괄적 인 이해를 제공하기 위해 기능적 웹 프레임 워크를 사용하여 간단한 예제 프로젝트를 만들었습니다. 주소를 다운로드하십시오
읽어 주셔서 감사합니다. 도움이되기를 바랍니다. 이 사이트를 지원 해주셔서 감사합니다!