利用Spring MVC搭建REST Service
之前写过一篇 利用JAX-RS快速开发RESTful 服务 今天来看下spring-mvc框架如何实现类似的功能:
一、pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>infosky</groupId>
<artifactId>Spring-MVC-REST</artifactId>
<packaging>war</packaging>
<version>1.0</version>
<properties>
<java-version>1.6</java-version>
<spring.version>3.2.8.RELEASE</spring.version>
<org.aspectj-version>1.7.3</org.aspectj-version>
</properties>
<dependencies> <!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency> <!-- json -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.3</version>
</dependency> <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>1.9.9-redhat-2</version>
</dependency> <!-- Logging -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency> <!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency> </dependencies> <profiles>
<profile>
<!-- 本地环境 -->
<id>local</id>
<properties> </properties>
</profile>
<profile>
<!-- 开发环境 -->
<id>dev</id>
<properties> </properties>
<!-- 默认激活本环境 -->
<activation>
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<profile>
<!-- 测试环境 -->
<id>test</id>
<properties> </properties>
</profile>
<profile>
<!-- 预发布环境 -->
<id>pre</id>
<properties> </properties>
</profile>
<profile>
<!-- 生产环境 -->
<id>prod</id>
<properties> </properties>
</profile>
</profiles> <build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>utf-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<organization>
<name>infosky</name>
<url>www.infosky.com.cn</url>
</organization>
</project>
二、web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:root-context.xml</param-value>
</context-param>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:servlet-context.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> </web-app>
三、servlet-context.xml (关键配置)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <mvc:annotation-driven />
<context:component-scan base-package="com.cnblogs.yjmyzz" />
<mvc:resources mapping="/resources/**" location="/resources/" /> <bean
class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="order" value="1" />
<property name="favorParameter" value="false" />
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="text/html" />
<property name="mediaTypes">
<map>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>
</list>
</property>
<property name="defaultViews">
<list>
<bean id="jsonView"
class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
<bean id="xmlView"
class="org.springframework.web.servlet.view.xml.MarshallingView">
<constructor-arg>
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>com.cnblogs.yjmyzz.dto.UserInfo</value>
<value>com.cnblogs.yjmyzz.dto.ListBean</value>
</list>
</property>
</bean>
</constructor-arg>
</bean>
</list>
</property>
</bean> </beans>
注:46,47行对应 Rest Service中涉及的对象类名,根据需要自行添加。
四、DTO对象
package com.cnblogs.yjmyzz.dto; import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement; import com.cnblogs.yjmyzz.utils.DateUtil;
import com.cnblogs.yjmyzz.utils.ListUtil; @XmlRootElement(name = "user")
public class UserInfo implements Serializable { private static final long serialVersionUID = -5461373449802431627L;
private String userName;
private BigDecimal salary;
private Date birthday;
private boolean isVip;
private int id;
private ListBean hobbies; @XmlElement
public String getUserName() {
return userName;
} public void setUserName(String userName) {
this.userName = userName;
} @XmlElement
public BigDecimal getSalary() {
return salary;
} public void setSalary(BigDecimal salary) {
this.salary = salary;
} @XmlElement
public Date getBirthday() {
return birthday;
} public void setBirthday(Date birthday) {
this.birthday = birthday;
} @XmlElement
public boolean isVip() {
return isVip;
} public void setVip(boolean isVip) {
this.isVip = isVip;
} @XmlElement
public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} @XmlElement
public ListBean getHobbies() {
return hobbies;
} public void setHobbies(ListBean hobbies) {
this.hobbies = hobbies;
} public String toString() {
return "id:" + this.id + ",userName:" + this.userName + ",isVip="
+ this.isVip + ",birthday="
+ DateUtil.formatDate(this.birthday) + ",hobbies:"
+ ListUtil.getString(this.hobbies.getList());
} }
为了实现List的XML序列化,还需要一个辅助类ListBean
package com.cnblogs.yjmyzz.dto; import java.util.List; import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElements;
import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "list")
public class ListBean { public ListBean() {
} public ListBean(List<?> list) {
this.list = list;
} private List<?> list; @XmlElements({ @XmlElement(name = "user", type = UserInfo.class),
@XmlElement(name = "hobby", type = String.class)
// 如果还有其它类型,继续添加
})
public List<?> getList() {
return list;
} public void setList(List<?> list) {
this.list = list;
}
}
注:25行getList前的注解,根据实际需要自行修改
五、Controller
package com.cnblogs.yjmyzz.web.controller; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod; import com.cnblogs.yjmyzz.dto.ListBean;
import com.cnblogs.yjmyzz.dto.UserInfo;
import com.cnblogs.yjmyzz.service.UserService; @Controller
@RequestMapping(value = "/rest", method = RequestMethod.GET)
public class RestController { @Autowired
UserService userService; @RequestMapping(value = "/user/{id}", method = RequestMethod.GET)
public UserInfo show(@PathVariable int id, HttpServletRequest request,
HttpServletResponse response) throws Exception {
return userService.getUserInfo(id); } @RequestMapping(value = "/user/list", method = RequestMethod.GET)
public ListBean getAll() throws Exception {
return userService.getAllUsers(); } }
其中UserService的代码为:
package com.cnblogs.yjmyzz.service; import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.cnblogs.yjmyzz.dto.ListBean;
import com.cnblogs.yjmyzz.dto.UserInfo;
import com.cnblogs.yjmyzz.utils.DateUtil; @Service("userService")
public class UserService { @Autowired
UserInfo defaultUserInfo; List<UserInfo> userInfos = null; public UserService() {
init();
} private void init() {
userInfos = new ArrayList<UserInfo>();
UserInfo user1 = new UserInfo();
user1.setBirthday(DateUtil.getDate(1985, 1, 1));
user1.setId(1);
user1.setUserName("A");
user1.setVip(true);
user1.setSalary(new BigDecimal(5000.00d));
List<String> hobbyNames = new ArrayList<String>();
hobbyNames.add("music");
hobbyNames.add("movie");
user1.setHobbies(new ListBean(hobbyNames));
userInfos.add(user1); UserInfo user2 = new UserInfo();
user2.setBirthday(DateUtil.getDate(1988, 10, 2));
user2.setId(2);
user2.setUserName("B");
user2.setVip(false);
user2.setSalary(new BigDecimal(8000.60d));
userInfos.add(user2); } public UserInfo getUserInfo(int userId) {
for (UserInfo u : userInfos) {
if (u.getId() == userId) {
return u;
}
}
return defaultUserInfo; } public ListBean getAllUsers() {
return new ListBean(userInfos);
}
}
其中DefaultUserInfo是通过配置由Spring注入的默认用户对象
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="dateFormat" class="java.text.SimpleDateFormat">
<constructor-arg value="yyyy-MM-dd" />
</bean> <bean name="defaultUserBean" class="com.cnblogs.yjmyzz.dto.UserInfo">
<property name="userName" value="匿名"></property>
<property name="salary" value="1000.00"></property>
<property name="vip" value="false"></property>
<property name="id" value="-1"></property>
<property name="birthday">
<bean factory-bean="dateFormat" factory-method="parse">
<constructor-arg value="1985-06-01" />
</bean>
</property>
</bean> </beans>
效果:
http://localhost:8080/Spring-MVC-REST/rest/user/1.json (返回json格式)
http://localhost:8080/Spring-MVC-REST/rest/user/1.xml (返回xml格式)
上面都是GET的示例,最后来一个POST的demo:
@RequestMapping(value = "/user/create", method = RequestMethod.POST)
@ResponseBody
public UserInfo create(@RequestBody(required=true) UserInfo user, HttpServletRequest request,
HttpServletResponse response) throws Exception {
logger.debug("日志记录成功:" + user);
user.setId(9999);//只是示例下,模拟db生成了主键id
return user;
}
源代码下载:Spring-MVC-REST.zip
最后附上一个链接,关于@RequestParam、@RequestBody、@RequestHeader、@CookieValue 这堆注解的用途,可参看这里
http://blog.csdn.net/kobejayandy/article/details/12690161
利用Spring MVC搭建REST Service的更多相关文章
- 【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回
作者:ssslinppp 时间:2015年5月26日 15:32:51 1. 摘要 本文讲解如何利用spring MVC框架,实现ajax异步请求以及json数据的返回. Spring MV ...
- [翻译]Spring MVC RESTFul Web Service CRUD 例子
Spring MVC RESTFul Web Service CRUD 例子 本文主要翻译自:http://memorynotfound.com/spring-mvc-restful-web-serv ...
- 利用Spring MVC 上传图片文件
本文转自:http://amcucn.iteye.com/blog/264457.感谢作者 近日在工作当中,需要用到上传图片的功能,然而自己平时学习的时候只会使用struts的上传功能,但因为项目并没 ...
- Spring MVC 搭建
1.新建一个 Java Web 项目 1-1 File > New >other 1.2 再 点击 Next 之后把 两个都勾选上 如下图 2 点击项目 > 鼠标右键 > ...
- Spring mvc 搭建Mybatis
本文建立在spring mvc已经搭建起来的基础上. 首先看要引入的jar包,其中高亮的是为了mybatis新引入的. <properties> <spring.webm ...
- spring mvc中的service和controller中读取不到properties值
根据web.xml读取配置文件中的顺序来看 controller层和service层来自于spring mvc.xml中读取,所以必须要在spring mvc.xml中配置读取资源文件夹方式
- Spring MVC——搭建HelloWeb工程
1.确保环境配置配置正确(Myeclipse(eclipse)+Tomcat) 2.新建web project 3.将Spring MVC所需的jar包粘贴到WebRoot/WEB-INF/lib下 ...
- Spring MVC 搭建过程中web.xml配置引入文件的路径问题
为啥要说一下这么low的问题,因为我是一个比较low的人,哈哈.本来我技术有限,没事干自己撘个环境找找乐趣,结果被各种基础问题,弄的一脸蒙蔽.算了不多说,直接说问题. 1.首先说一下java编译后的文 ...
- Spring MVC 搭建web项目示例
环境为Eclipse 1:新建Dynamic web project : springMvcDemo 2:下载spring的jar包,把jar包复制到WEB-INF/lib目录下 3.添加配置文件w ...
随机推荐
- sshd安装
centos yum install openssh-server #chkconfig --level 2345 sshd on #service sshd restart 重新启动 #netsta ...
- 学习 jsonp
1.起因 js脚本做ajax异步调用的时候,直接请求普通文件存在跨域无权限访问的问题,不管你是静态页面.动态网页.web服务,只要是跨域请求,都无法成功: 如果上句话没明白,我们直接看例子.有两个一模 ...
- png-8 和 png-24的区别
png是一种图片格式,是Portable Networks Graphics的缩写,做ping. png8和png24的区别如下. 1 "PNG8"是指8位索引色位图," ...
- python 打印对象的所有属性值
def prn_obj(obj): print '\n'.join(['%s:%s' % item for item in obj.__dict__.items()])
- 由一个订单推送想到了ObservableCollection的神奇用法
最近在做taobao的一个卖家应用,需要订阅taobao的订单推送,示例代码如下: 看到上面的OnMessage场景之后,我突然就鬼使神差的在想最近写的一个服务,其中的一个功能是需要定时的轮询一个集合 ...
- 【Html5】Html5新特性Notification实现桌面消息推送(2016-05-25)
序:最近工作使用WorkTile,发现使用Chrome浏览器的时候如果有任务下发给我则会在桌面右下角提示(当前浏览器为最小化模式).感觉这个东西蛮有意思的,感觉可以给用户更好的体验,于是乎就查询了一下 ...
- Java api 入门教程 之 JAVA的String 类
1.String对象的初始化 由于String对象特别常用,所以在对String对象进行初始化时,Java提供了一种简化的特殊语法,格式如下: String s = “abc”; s = “Java语 ...
- linux下如何打包压缩?解包解压?.tar文件.gz文件
===文件打包.压缩 ==打包 tar [root@521478.com]# tar -cvf etc1.tar /etc //c创建 v详细 f打包后文件名 [root@521478.com]# t ...
- RAID详解[RAID0/RAID1/RAID10/RAID5]
一.RAID定义RAID(Redundant Array of Independent Disk 独立冗余磁盘阵列)技术是加州大学伯克利分校1987年提出,最初是为了组合小的廉价磁盘来代替大的昂贵磁盘 ...
- android 设置布局横屏竖屏
只要在AndroidManifest.xml里面配置一下就可以了.在AndroidManifest.xml的activity(需要禁止转向的activity)配置中加入android:screenOr ...