【前言】这是我学习Spring框架的第一篇,之前看过几本介绍Spring框架的书,上面都是用context.xml文件完成bean配置。最近自己阅读spring官方网站,发现全部是用注解,没有一行xml配置。为了跟上时代,我决定把官网教程读一遍,在这里放上阅读笔记。
【原文链接】http://spring.io/guides/gs/rest-service/
【实现目标】创建一个web服务,能够响应形如:http://localhost:8080/greeting 这样的get请求。响应页面是一个Json,看起来应该是这样的,{"id":1,"content":"Hello, World!"}
。也可以给get请求带上参数http://localhost:8080/greeting?name=User 这样的话,响应页面看起来应该是这样的{"id":1,"content":"Hello,User!"}
。
【准备工作】
按照原文给的方法进行。
如果是用Eclipse的maven创建工程,需要在pom.xml中设置依赖关系,最好按照原文maven配置方法添加pom.xml中的属性。否则org.springframework.web.bind.annotation.*无法导入。
一切准备好之后,现在可以创建自己的web server了。开始我们想想web服务是怎么交互的:server先处理对/greeting的GET请求,GET可以带个参数name。然后server返回200 OK,并用一个Json最为应答正文,这个Json看起来像这样:
{ "id": 1, "content": "Hello, World!" }
id域是每个greeting的唯一标识,content域代表问候语。
为了给问候语建模,现在需要一个类来表示问候语,这个类只需要简单的几个东西:id、content域,构造器,域访问器
package hello; public class Greeting { private final long id; private final String content; public Greeting(long id, String content) { this.id = id; this.content = content; } public long getId() { return id; } public String getContent() { return content; } }
用Spring框架实现的web server中,HTTP请求都由控制器来处理。控制器部分可以用@RestController
注解来标注。下面的GreetingController类就是用来处理greeting请求的控制器,它的greeting方法响应对/greeting页面的get请求,并返回一个Greeting对象。
package hello; import java.util.concurrent.atomic.AtomicLong; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; @RestController public class GreetingController { private static final String template = "Hello, %s!"; private final AtomicLong counter = new AtomicLong(); @RequestMapping("/greeting") public Greeting greeting(@RequestParam(value="name", defaultValue="World") String name) { return new Greeting(counter.incrementAndGet(), String.format(template, name)); } }
这个控制器类很简单,但其中有很多潜在的东西,下面逐步进行说明。
传统MVC和RESTfull web server的关键不同点在于,HTTP响应体的生成方式。传统MVC基于视图的方式会在server端渲染成HTML格式的问候语greeting,而后者只是简单计数(指id计数),控制器只需返回Greeting对象,而这个Greeting对象将由框架以Json的方式写入HTML。
这里使用了Spring4最新的注解@RestController
将一个类声明为控制器,该类中所有的处理请求的方法都返回对象而不是MVC中的View。这个注解是@Controller
和@ResponseBody
组合的简写。
Greeting对象必须转成Json。感谢Spring框架对Http消息的支持,你不需要自己完成这个转换。系统路径中有Jackson 2,Spring中的MappingJackson2HttpMessageConverter
功能会自动实现Bean到Json的转换。
虽然可以把工程打包成war部署在一个web应用服务上,不过下面会告诉你一个实现独立应用的方法。先把所有东西都打包成一个可运行的jar文件,当然,要有一个main()方法。下一步是将jar包部署在tomcat servlet容器上面作为HTTP运行环境。
package hello; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
@SpringBootApplication
注解意味着以下工作:
@Configuration
标记的类作为applicationContext中bean的定义(不再需要写.xml文件了)。
@EnableAutoConfiguration
告诉Spring Boot 添加classpath 中指定的bean、其他bean、和各种属性设置。
一般你需要为Spring MVC 应用添加 @EnableWebMvc
注解,不过Spring Boot在发现classpath中含有spring-webmvc时会自动添加。这个注解标记应用为web应用,同时激活一些关键行为,例如启动一个servlet转发器。
@ComponentScan
告诉Spring在hello包中扫描其他部分、配置、服务来定位HelloController。
main()方法是用了Spring Boot的SpringApplication.run()
方法启动应用。你是否注意到这里没有一行XML,也没有web.xml。本工程是100%纯java工程,不需要做任何配置(用注解就是这样~)。
运行./gradlew bootRun
。你可以创建一个单独的可执行JAR文件,包含了所有必须的依赖文件,类,资源。这样做能很容易的在开发周期中在不同环境之间完成移植,发布版本,部署服务。此时你可以这样:./gradlew build 然后就可以运行java -jar build/libs/gs-rest-service-0.1.0.jarmvn spring-boot:run
. 或者你可以buildmvn clean package
然后运行JAR: java -jar target/gs-rest-service-0.1.0.jar
经过测试,发现一些有意思的东西。
【小结】熟悉掌握控制器中的注解@RestController @RequestMapping @RequestParam,应用入口的注解@SpringBootApplication,以及Spring Boost入口SpringApplication.run()