SpringMVC使用Jetty作為內嵌伺服器
Jetty 是高效能的 Servlet 容器,經常會在開發環境中作為伺服器來使用。在本文中,我們將使用 Spring Web MVC 技術來實現 REST 介面,並使用 使用 Jetty 作為內嵌伺服器,方便測試。
介面設計
我們將會在系統中實現兩個介面:
其中,第一個介面“/hello”將會返回“Hello World!” 的字串;而第二個介面“/hello/way”則會返回一個包含使用者資訊的JSON字串。
系統配置
我們需要在應用中新增如下依賴:
<properties>
<spring.version>5.0.4.RELEASE</spring.version>
<jetty.version>9.4.9.v20180320</jetty.version>
<jackson.version>2.9.4</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
其中,
-
spring-webmvc
是為了使用 Spring MVC 的功能。 -
jetty-servlet
是為了提供內嵌的 Servlet 容器,這樣我們就無需依賴外部的容器,可以直接執行我們的應用。 -
jackson-core
和jackson-databind
為我們的應用提供 JSON 序列化的功能。
後臺編碼實現
領域模型
建立一個 User 類,代表使用者資訊。
public class User {
private String username;
private Integer age;
public User(String username, Integer age) {
this.username = username;
this.age = age;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
控制器
建立 HelloController 用於處理使用者的請求。
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
return "Hello World! Welcome to visit waylau.com!";
}
@RequestMapping("/hello/way")
public User helloWay() {
return new User("Way Lau", 30);
}
}
其中,對映到“/hello”的方法將會返回“Hello World!” 的字串;而對映到“/hello/way”則會返回一個包含使用者資訊的JSON字串。
應用配置
在本應用中,我們採用基於 Java 註解的配置。
AppConfiguration 是我們的主應用配置:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@ComponentScan(basePackages = { "com.waylau.spring" })
@Import({ MvcConfiguration.class })
public class AppConfiguration {
}
AppConfiguration 會掃描“com.waylau.spring”包下的檔案,並自動將相關的 bean 進行註冊。
AppConfiguration 同時又引入了 MVC 的配置類 MvcConfiguration:
@EnableWebMvc
@Configuration
public class MvcConfiguration implements WebMvcConfigurer {
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJackson2HttpMessageConverter());
}
}
MvcConfiguration 配置類一方面啟用了 MVC 的功能,另一方面新增了 Jackson JSON 的轉換器。
最後,我們需要引入 Jetty 伺服器 JettyServer:
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
import com.waylau.spring.mvc.configuration.AppConfiguration;
public class JettyServer {
private static final int DEFAULT_PORT = 8080;
private static final String CONTEXT_PATH = "/";
private static final String MAPPING_URL = "/*";
public void run() throws Exception {
Server server = new Server(DEFAULT_PORT);
server.setHandler(servletContextHandler(webApplicationContext()));
server.start();
server.join();
}
private ServletContextHandler servletContextHandler(WebApplicationContext context) {
ServletContextHandler handler = new ServletContextHandler();
handler.setContextPath(CONTEXT_PATH);
handler.addServlet(new ServletHolder(new DispatcherServlet(context)), MAPPING_URL);
handler.addEventListener(new ContextLoaderListener(context));
return handler;
}
private WebApplicationContext webApplicationContext() {
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
context.register(AppConfiguration.class);
return context;
}
}
JettyServer 將會在 Application 類中進行啟動:
public class Application {
public static void main(String[] args) throws Exception {
new JettyServer().run();;
}
}
11.13.6 執行
在編輯器中,直接執行 Application 類即可。啟動之後,應能看到如下控制檯資訊:
2018-03-21 23:14:52.665:INFO::main: Logging initialized @203ms to org.eclipse.jetty.util.log.StdErrLog
2018-03-21 23:14:52.868:INFO:oejs.Server:main: jetty-9.4.9.v20180320; built: 2018-03-20T20:21:10+08:00; git: 1f8159b1e4a42d3f79997021ea1609f2fbac6de5; jvm 1.8.0_112-b15
2018-03-21 23:14:52.902:INFO:oejshC.ROOT:main: Initializing Spring root WebApplicationContext
三月 21, 2018 11:14:52 下午 org.springframework.web.context.ContextLoader initWebApplicationContext
資訊: Root WebApplicationContext: initialization started
三月 21, 2018 11:14:52 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
資訊: Refreshing Root WebApplicationContext: startup date [Wed Mar 21 23:14:52 CST 2018]; root of context hierarchy
三月 21, 2018 11:14:52 下午 org.springframework.web.context.support.AnnotationConfigWebApplicationContext loadBeanDefinitions
資訊: Registering annotated classes: [class com.waylau.spring.mvc.configuration.AppConfiguration]
三月 21, 2018 11:14:53 下午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry register
資訊: Mapped "{[/hello]}" onto public java.lang.String com.waylau.spring.mvc.controller.HelloController.hello()
三月 21, 2018 11:14:53 下午 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping$MappingRegistry register
資訊: Mapped "{[/hello/way]}" onto public com.waylau.spring.mvc.vo.User com.waylau.spring.mvc.controller.HelloController.helloWay()
三月 21, 2018 11:14:53 下午 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter initControllerAdviceCache
資訊: Looking for @ControllerAdvice: Root WebApplicationContext: startup date [Wed Mar 21 23:14:52 CST 2018]; root of context hierarchy
三月 21, 2018 11:14:53 下午 org.springframework.web.context.ContextLoader initWebApplicationContext
資訊: Root WebApplicationContext: initialization completed in 983 ms
2018-03-21 23:14:53.893:INFO:oejshC.ROOT:main: Initializing Spring FrameworkServlet `org.springframework.web.servlet.DispatcherServlet-6aaa5eb0`
三月 21, 2018 11:14:53 下午 org.springframework.web.servlet.FrameworkServlet initServletBean
資訊: FrameworkServlet `org.springframework.web.servlet.DispatcherServlet-6aaa5eb0`: initialization started
三月 21, 2018 11:14:53 下午 org.springframework.web.servlet.FrameworkServlet initServletBean
資訊: FrameworkServlet `org.springframework.web.servlet.DispatcherServlet-6aaa5eb0`: initialization completed in 15 ms
2018-03-21 23:14:53.910:INFO:oejsh.ContextHandler:main: Started o.e.j.s.ServletContextHandler@2796aeae{/,null,AVAILABLE}
2018-03-21 23:14:54.037:INFO:oejs.AbstractConnector:main: Started ServerConnector@42054532{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
2018-03-21 23:14:54.038:INFO:oejs.Server:main: Started @1578ms
分別在瀏覽器中訪問 “http://localhost:8080/hello” 和 “http://localhost:8080/hello/way” 地址進行測試,能看到圖1和圖2的響應效果。
圖1 “/hello”介面的返回內容
圖2 “/hello/way”介面的返回內容
參考應用
- 原始碼:見《Spring 5 案例大全》(https://github.com/waylau/spring-5-book)的 “s5-ch11-mvc-rest”應用。
- 原文同步至:https://waylau.com/spring-mvc-use-jetty/
相關文章
- 【譯】用maven使java web應用執行在內嵌的Jetty或TomMavenJavaWebJetty
- javafx內嵌為Swing程式淺析Java
- Jetty的配置、部署與API使用——(3)Linux下利用Jetty API執行一個Jetty伺服器JettyAPILinux伺服器
- Jetty的配置、部署與API使用——(2)通過Jetty的Java API執行一個Jetty伺服器JettyAPIJava伺服器
- Myeclipse中maven工程使用jetty外掛啟動jetty伺服器除錯EclipseMavenJetty伺服器除錯
- Oracle與MySQL內嵌遊標的使用示例OracleMySql
- JDK中內嵌JS引擎介紹及使用JDKJS
- Nginx 內嵌變數Nginx變數
- Jetty使用入門Jetty
- 使用iframe內嵌網頁的時候,如何做到內嵌網頁的高度自適應 有大用網頁
- MongoDB查詢內嵌文件MongoDB
- centos8使用chrony作為NTP伺服器CentOS伺服器
- Jetty使用總結薦Jetty
- 淺談小程式內嵌網頁及內嵌網頁跳轉分享實現網頁
- 小程式內嵌h5H5
- 禁用內嵌檢視的排序排序
- Jetty的配置、部署與API使用——(1)下載安裝JettyJettyAPI
- SpringMVC系列知識:(二)什麼是springMVC,為什麼要使用springMVCSpringMVC
- SVG 立方體內嵌路徑拼接SVG
- 客戶端內嵌Vue頁面客戶端Vue
- C++內嵌彙編 教程1C++
- Django的訊息中內嵌HTMLDjangoHTML
- Spring Boot移除內嵌Tomcat,使用非web方式啟動Spring BootTomcatWeb
- Jetty的安裝、配置和使用Jetty
- Debug: calc() 未生效 <= 內嵌樣式表示式需使用空格分隔
- Android/iOS內嵌Unity開發示例AndroidiOSUnity
- Spring Boot 內嵌容器 Tomcat / UndertowSpring BootTomcat
- Go 內嵌靜態檔案工具 packrGo
- 使用Chrome開發者工具除錯Android端內網頁(微信,QQ,UC,App內嵌頁等)Chrome除錯Android內網網頁APP
- 在Ubuntu上使用Jetty部署War包UbuntuJetty
- Maven Jetty Plugin執行配置jetty:runMavenJettyPlugin
- PostgreSQLoracle相容性-字串內嵌NULL字元(空字元)chr(0)轉換為chr(32)SQLOracle字串Null字元
- 在APP中內嵌遊戲,網際網路廠商為何紛紛”上癮“APP遊戲
- AdWhirl:iPhone,Android軟體內嵌廣告iPhoneAndroid
- Larvel 操作 MongoDB(對內嵌陣列增刪改)MongoDB陣列
- 2分鐘學會CSS內嵌樣式CSS
- C指標原理(8)-C內嵌彙編指標
- C指標原理(6)-C內嵌彙編指標