簡體   English   中英

Spring Boot + Spring MVC + Ratpack可能嗎?

[英]Is Spring Boot + Spring MVC + Ratpack possible?

我們是一個Spring Boot商店,並且非常依賴Spring MVC作為我們的REST端點。 我們使用Boot和嵌入式Tomcat來創建自托管JAR。 是否可以用Ratback替換Tomcat,同時仍然保留我的所有Spring MVC代碼? 我擔心Spring MVC會以某種方式綁定到servlet規范中,並且不會在沒有servlet容器的情況下運行。 我知道dsyer / spring-boot-ratpack的工作,但在略讀之后,代碼無法決定Spring MVC是否能夠很好地使用橋接器。 是否有人知道任何可以讓我們保留對Spring MVC的投資並讓Spring Boot使用Ratpack來管理HTTP流量的工作?

我懷疑你的問題的症結可以歸結為:“我們可以把我們的Spring控制器放在Ratpack的非阻塞HTTP層之上嗎?” 對這個問題最簡單的答案是否定的,因為MVC編程模型不能很好地適應被動/ NIO模型。

但是,如果您的應用程序遵循一些常見的模型 - 視圖 - 控制器 - (和服務)模式,那么您的控制器應該只是執行數據綁定和解析並委派給服務層。 如果是這種情況,那么控制器中的代碼可能已經非阻塞,您可以輕松地將其轉換為Ratpack代碼。

作為示例,請考慮Spring Boot應用程序中的以下@RestController

@RestController
@RequestMapping("/user")
class UserController {

  @Autowired
  UserService userService

  @RequestMapping(method = RequestMethod.POST)
  Long create(@RequestBody @Valid User user) {
    User savedUser = userService.save(user)
    return savedUser.id
  }
}

Spring的數據綁定方面是一個計算過程(即不受I / O限制),因此我們可以輕松地將其轉換為Ratpack處理程序:

import app.SpringConfig
import app.User
import app.UserService
import org.springframework.boot.SpringApplication
import org.springframework.context.ApplicationContext
import ratpack.jackson.JacksonModule

import static ratpack.groovy.Groovy.ratpack
import static ratpack.jackson.Jackson.fromJson
import static ratpack.jackson.Jackson.json
import static ratpack.spring.Spring.spring

ratpack {
  bindings {
    add(new JacksonModule())
    bindInstance(ApplicationContext, SpringApplication.run(SpringConfig))
  }
  handlers { ApplicationContext ctx ->
    register(spring(ctx))

    prefix("user") {
      handler { UserService userService ->
        byMethod {
          post {
            def user = parse(fromJson(User))
            blocking {
              userService.save(user)
            } then { User savedUser ->
              render(json(savedUser))
            }
          }
        }
      }
    }
  }
}

SpringConfig看起來像這樣:

package app

import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration

@Configuration
class SpringConfig {
  @Bean
  UserService userService() {
    new UserService()
  }
}

這是一個功能測試來證明它:

package app

import com.fasterxml.jackson.databind.ObjectMapper
import ratpack.groovy.test.GroovyRatpackMainApplicationUnderTest
import ratpack.test.ApplicationUnderTest
import ratpack.test.http.TestHttpClient
import spock.lang.Shared
import spock.lang.Specification

import static groovy.json.JsonOutput.toJson

class FuncSpec extends Specification {
  @Shared ApplicationUnderTest aut = new GroovyRatpackMainApplicationUnderTest()
  @Shared ObjectMapper mapper = new ObjectMapper()
  @Delegate TestHttpClient client = aut.httpClient
  def "should parse and save user"() {
    given:
    def user = new User(username: "dan", email: "danielpwoods@gmail.com")

    when:
    requestSpec { spec ->
      spec.body { b ->
        b.type("application/json")
        b.text(toJson(user))
      }
    }
    post('user')

    then:
    def savedUser = mapper.readValue(response.body.text, User)

    and:
    savedUser.id
  }
}

希望這可以幫助!

Spring MVC編程模型並不是非常依賴於Servlet API,但是在任何其他容器中都不支持它(即不在Ratpack中)。 現在有一些異步的東西,Servlet 3.1增強了它,所以如果這是吸引你的Ratpack的一部分,也許只是使用它將是一個更好的方法。 盡管如此,你不會一直到反應和非阻塞IO。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM