基于Spring 4.0和Servlet 3.0编写无XML配置的REST服务
实现效果
1. 发送请求到:
1 | http://localhost:8080/app/user/123 |
2. 服务器返回JSON:
1 | {"id":123,"user":null,"nickname":null,"realname":null} |
详细步骤
1. 下载并安装SpringTool Suite (STS)。
虽然Spring开发不一定要使用STS,只需要安装好Eclipse WTP(带有Maven),但是最新版本的STS(3.4.0)比较稳定,这个练习是采用这个工具开发。另外,最好根据自己的机器配置优化一下STS的运行参数,我的电脑有12G内存,STS.ini的配置如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | -startup plugins/org.eclipse.equinox.launcher_1.3.0.v20130327-1440.jar --launcher.library plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.200.v20130807-1835 -product org.springsource.sts.ide --launcher.defaultAction openFile --launcher.XXMaxPermSize 1024M -vmargs -Dorg.eclipse.swt.browser.IEVersion=10001 -Dosgi.requiredJavaVersion=1.6 -Xms512m -Xmx2048m -XX:PermSize=512m -XX:MaxPermSize=1024m -XX:CompileThreshold=1000 |
2. 使用Maven的Servlet3 Archetype创建项目:
3. 编写Web应用初始化程序,告诉Servlet 3容器如何启动Servlet——相当于Servlet 2.x的web.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | public class SpringWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override protected Class<?>[] getRootConfigClasses() { return new Class[] { AppConfig.class }; }
@Override protected Class<?>[] getServletConfigClasses() { return new Class[] { WebConfig.class }; }
@Override protected String[] getServletMappings() { return new String[] { "/" }; }
@Override protected Filter[] getServletFilters() { return super.getServletFilters(); }
} |
AppConfig负责告诉Spring如何加载Bean,我们这里就是让它自动扫描代码注释来解析Bean:
1 2 3 | @Configuration @ComponentScan(value = "com.zengsource.restwithspring") public class AppConfig { } |
WebConfig负责告诉Spring如何加载控制器:
1 2 3 4 | @EnableWebMvc @Configuration @ComponentScan(value = "com.zengsource.restwithspring") public class WebConfig extends WebMvcConfigurerAdapter { } |
注意:这里一定要通过@ComponentScan告诉Spring,否则容器无法找到所编写的控制器,会出现找不到URI绑定的错误提示,这时请求无法映射到所编写的控制器上。
4. 编写控制器:
1 2 3 4 5 6 7 8 9 10 | @Controller @RequestMapping("/user") public class UserController { @RequestMapping(value="/{uid}", method = RequestMethod.GET) public @ResponseBody UserInfo view(@PathVariable @NumberFormat int uid, Model model) { UserInfo userInfo = new UserInfo(); userInfo.setId(uid); return userInfo; } } |
注意:这里必要在工程的classpath中加入Jackson的JAR,参见我的pom.xml:
1 2 3 4 5 6 7 | org.codehaus.jackson jackson-core-asl 1.9.13
org.codehaus.jackson jackson-mapper-asl 1.9.13 |
参考资料
- http://maciejwalkowiak.github.io/servlet3-maven-archetype/
- http://spring.io/guides/gs/rest-service/
- http://kielczewski.eu/2013/11/spring-mvc-without-web-xml-using-webapplicationinitializer/
- http://stackoverflow.com/questions/7462202/spring-json-request-getting-406-not-acceptable