这篇文章主要围绕Spring4.x实现Restfulwebservice和spring的restful展开,旨在为您提供一份详细的参考资料。我们将全面介绍Spring4.x实现Restfulwebse
这篇文章主要围绕Spring 4.x实现Restful web service和spring的restful展开,旨在为您提供一份详细的参考资料。我们将全面介绍Spring 4.x实现Restful web service的优缺点,解答spring的restful的相关问题,同时也会为您带来Apache CXF 和 Spring 开发RESTful Web Service 2、CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services、CXF+Spring+Hibernate 实现 RESTful webservice 服务端示例、java – Spring:文件上传RESTFUL Web Service的实用方法。
本文目录一览:- Spring 4.x实现Restful web service(spring的restful)
- Apache CXF 和 Spring 开发RESTful Web Service 2
- CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services
- CXF+Spring+Hibernate 实现 RESTful webservice 服务端示例
- java – Spring:文件上传RESTFUL Web Service
Spring 4.x实现Restful web service(spring的restful)
Spring 4.x实现Restful web service 博客分类: spring首先我们还是跟之前一样,创建一个maven项目,不过因为Spring Restful web service是基于Spring 4.x版本的,所以我在这里就直接将Spring升级到了4.0.8,下面我贴出我的pom文件主要的依赖:
<properties>
<spring.version>4.0.8.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</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-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.4</version>
</dependency>
<!-- web项目编译时需要,部署到tomcat中就不需要了 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<!-- web项目编译时需要,部署到tomcat中就不需要了 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.3.4</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.8.5</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.4.3</version>
</dependency>
</dependencies>
<repositories>
<repository>
<id>spring-releases</id>
<url>https://repo.spring.io/libs-release</url>
</repository>
</repositories>
这里有spring,springMVC,jackson及编译时需要的servlet-api及jsp-api依赖,就没有其他多余的依赖了。因为spring是原生支持Jackson,所以我这里并没有选择使用我常用的fastjson,或者gson。当然,如果你们在自己的项目中使用的是fastjson,或gson的话,也没有关系,替换使用的话也还是很方便与简单的,这里不做详细介绍。
添加依赖后,就是配置web文件了。创建一个Restful web service与普通的springMVC项目没有什么区别,所以web配置也跟大家创建普通springMVC项目一样,简单的只需要配置一下servlet与servlet-mapping就可以了。然后就是指定springMVC配置文件,并添加到init-param或context-param中就可以了。
<context:component-scan base-package="com.yyd.spring.aop.rest.controller" />
<bean/>
<bean>
<property name="messageConverters">
<list>
<bean/>
</list>
</property>
</bean>
@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.getAndIncrement(),String.format(template, name));
}
}
这里我们看到控制器上的注解由我们经常使用的@Controller变成了@RestController。@RestControllr是spring 4.x中的新注解,@RestController,表明该类的每个方法返回对象而不是视图。它实际就是@Controller和@ResponseBody混合使用的简写方法。@ResponseBody的作用是将返回的对象放入响应消息体中("其实大家都懂的,啰嗦了一句。")。
然后大家就可以启动tomcat或jetty服务器,在浏览器中输入:
http:
//localhost:8080/greeting
然后就可以看到浏览器返回的结果了,
{
"id"
:
1
,
"content"
:
"Hello, World!"
}
至此,一个简单的基于Spring 4.x的Restful web service框架就已经完成,谢谢大家,希望对大家有所帮助。
http://my.oschina.net/yuyidi/blog/352909
Apache CXF 和 Spring 开发RESTful Web Service 2
###开发环境 Maven Eclipse Tomcat
###快速构建 archetype太少?关于如何添加本地archetype catalog:
下载文件 http://repo1.maven.org/maven2/archetype-catalog.xml 设置Eclipse 首选项 Maven Archetype ,将archetype-catalog.xml 添加为Local catalog.
使用Archetype 创建Maven项目,坐标:
org.apache.cxf.archetype
cxf-jaxrs-service 3.1.4
注释掉pom.xml文件中的插件配置,执行 mvn clean install
将项目发布到Tomcat服务器
我的项目名称为 my_cxf_restful
访问URL http://localhost:8080/my_cxf_restful/hello/echo/cong 网页显示结果为:
cong
###项目构建步骤 ####导入依赖包 导入jackson 是因为需要处理json类型数据
cxf-rt-frontend-jaxrs 为CXF 开发RESTful WebService 必须的包,其它依赖Maven会自动处理
项目基于Spring
<properties>
<jackson.version>1.8.6</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-client</artifactId>
<version>3.1.4</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-jaxrs</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.1.7.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
####编写RESTful WebService类: 这里并没有写成接口,而是直接写成实现类.
modifyJson方法中框架会将POST请求体的JSON 数据转换成对象JsonBean
注解说明,见下一条目
@Path("/hello")
public class HelloWorld {
@GET
@Path("/echo/{input}")
@Produces("text/plain")
public String ping(@PathParam("input") String input) {
return input;
}
@POST
@Produces("application/json")
@Consumes("application/json")
@Path("/jsonBean")
public Response modifyJson(JsonBean input) {
input.setVal2(input.getVal1());
return Response.ok().entity(input).build();
}
}
####注解说明: 本文段引用自http://www.ibm.com/developerworks/cn/opensource/os-restfulwebservices/index.html
(天啊!居然不支持表格)
- |标签|用法和解释|
- |@GET,@POST,@PUT,@DELETE| 该组标签将一个标注方法的 HTTP 请求类型|
- |@Path |该标签可用于类或者方法,表示定位此 RESTful 资源的路径|
- |@Produces |该标签标注资源类或方法返回的 MIME 类型 , 也就是资源方法产生并且返回给客户端的响应消息的类型。例如 application/xml,application/json.|
- |@Consumes |该标签标注资源类或方法可以接受的请求消息的类型,也就是客户端发送的请求中可以包含的 Http Entity 的类型。|
- |@PathParam,@QueryParam,@HeaderParam,@CookieParam |该组分别标注方法的参数来自于 HTTP 请求的不同位置,例如,@PathParam 来自于 URL 的路径,@QueryParam 来自于 URL 的查询参数,@HeaderParam 来自于 HTTP 请求的头信息,@CookieParam 来自于 HTTP 请求的 Cookie。|
- |@Context |该标签标注资源请求或者响应的上下文实例,例如我们可以再资源方法参数中注入 HttpServletRequest (@Context HttpServletRequest httpRequest) 来获取 Http 请求的相关信息。|
####Spring Bean 配置:
<?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:jaxrs="http://cxf.apache.org/jaxrs" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd">
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<context:property-placeholder/>
<context:annotation-config/>
<bean/>
<bean/>
<jaxrs:server id="services" address="/">
<jaxrs:serviceBeans>
<bean/>
</jaxrs:serviceBeans>
<jaxrs:providers>
<bean/>
</jaxrs:providers>
</jaxrs:server>
</beans>
####Web.xml配置: 与构建一个简单的WebService一样: 使用Spring监听器加载BEAN配置文件;
注册CXF Servlet处理请求.
<?xml version="1.0" encoding="utf-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4">
<display-name>JAX-RS Simple Service</display-name>
<description>JAX-RS Simple Service</description>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/beans.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
####测试
使用FireFox插件Open HTTPRequester post发送json数据
使用方法:使用firefox插件httperrequest,模拟发送及接收Json请求
####更多实例 下载Apache CXF 发布包
查看${CXF_HOME}/simple
例如 ...\apache-cxf-3.1.4\samples\jax_rs\basic
###参考资料: http://www.ibm.com/developerworks/cn/opensource/os-restfulwebservices/index.html
http://www.ibm.com/developerworks/cn/webservices/ws-pojo-springcxf2/index.html
CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services
CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services
1、访问:http://localhost:8088/sniperWS/services/
查看有哪些服务,包含 Available SOAP services、Available RESTful services
2、客户端调用 RESTful services:
http://localhost:8088/sniperWS/services/address/getSuggestions.query
调用示例:
$.ajax({
url: "http://ip:port/sniperWS/services/address/getSuggestions.query",
dataType: "json",
data : {
"address" : '' 罗湖 '',
"max":10,
"_type":"json"
},
cache : false,
success: function(data) {
var items = data.addressVO;
for(var index in items) {
alert(items[index].address);
}
},
error : function(error) {
alert(error);
}
});
ws-services-context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://cxf.apache.org/jaxws http://cxf.apache.org/schemas/jaxws.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd" default-autowire="byName">
<!--spring发布web服务配置 -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<bean id="addressService" class="cn.sniper.ws.service.AddressServiceImpl" />
<!-- 方式一:发布SOAP services -->
<!-- <jaxws:endpoint id="addressWS" implementor="#addressService" address="/addressWS" /> -->
<!-- 方式二:发布SOAP services -->
<jaxws:server id="addressWS" address="/addressWS">
<jaxws:serviceBean>
<ref bean="addressService" />
</jaxws:serviceBean>
<!-- <jaxws:inInterceptors>
<bean ></bean>
</jaxws:inInterceptors> -->
</jaxws:server>
<!-- 发布RESTful services-->
<jaxrs:server id="addressServiceWS" address="/address">
<jaxrs:extensionMappings>
<entry key="json" value="application/json" />
<entry key="xml" value="application/xml" />
</jaxrs:extensionMappings>
<jaxrs:serviceBeans>
<ref bean="addressService" />
</jaxrs:serviceBeans>
<!-- <jaxrs:inInterceptors>
<bean ></bean>
</jaxrs:inInterceptors> -->
</jaxrs:server>
</beans>
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=
xmlns:xsi=
xmlns:context=
xmlns:aop=
xmlns:tx=
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<context:component-scan base-package="cn.sniper.ws.service"></context:component-scan>
<import resource="ws-services-context.xml"/>
</beans>
AddressService
package cn.sniper.ws.service;
import java.util.List;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import cn.sniper.ws.po.Address;
@SOAPBinding(style = Style.DOCUMENT)
@WebService(targetNamespace = "http://cn.sniper.ws.service")
public interface AddressService {
public List<Address> getSuggestions(@WebParam(name="address")String address, @WebParam(name="max")int max);
}
AddressServiceImpl
package cn.sniper.ws.service;
import java.util.ArrayList;
import java.util.List;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.QueryParam;
import cn.sniper.ws.po.Address;
@Path(value="/")
@SOAPBinding(style = Style.DOCUMENT)
@WebService(
serviceName = "address",
portName = "address",
targetNamespace = "http://cn.sniper.ws.service",
endpointInterface = "cn.sniper.ws.service.AddressService")
public class AddressServiceImpl implements AddressService {
@GET
@Path("getSuggestions.query")
public List<Address> getSuggestions(@QueryParam("address")String address, @QueryParam("max")int max) {
List<Address> addressList = new ArrayList<Address>();
addressList.add(new Address(1L, "admin-1"));
addressList.add(new Address(2L, "admin-2"));
return addressList;
}
}
Address
package cn.sniper.ws.po;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
/**
* 注意,@XmlRootElement(name="addressVO")的name不要和属性的name重复,
* 否则会导xml解析过程报错
* @author audaque
*
*/
@XmlRootElement(name="addressVO")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {"id","address"})
public class Address implements Serializable {
private static final long serialVersionUID = -1704617795954765535L;
@XmlElement(name="id")
private Long id;
@XmlElement(name="address")
private String address;
public Address() {
}
public Address(Long id, String address) {
this.id = id;
this.address = address;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<!-- 通过上下文参数指定spring配置文件的位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/beans.xml</param-value>
</context-param>
<!-- spring上下文载入器监听器,确保web服务器启动时,完成spring容器的初始化 ,放在了application范围中-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- cxf -->
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
pom.xml
<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>cn.sniper.ws</groupId>
<artifactId>sniperWS</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>sniperWS Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.1.1.RELEASE</spring.version>
<struts.version>2.3.4.1</struts.version>
<hibernate.version>3.6.9.Final</hibernate.version>
<junit.version>4.8.1</junit.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-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-oxm</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>
<!-- 注解拦截,需要引入spring aop相关jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-hibernate3</artifactId>
<version>2.0.8</version>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib</artifactId>
<version>2.2.2</version>
</dependency>
<!-- aspectj -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjlib</artifactId>
<version>1.6.2</version>
</dependency>
<!-- @ResponseBody 将数据转换成json的依赖包,如果没有依赖包,即使能够访问action,返回的时候也会报错 -->
<!-- 解决:Could not find acceptable representation报错; 客户端报错:ajax not acceptable -->
<!-- <dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-core-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency> -->
<!-- cxf -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>apache-cxf</artifactId>
<version>2.6.1</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>net.sf.json-lib</groupId>
<artifactId>json-lib</artifactId>
<version>2.2.3</version>
<classifier>jdk15</classifier>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>sniperWS</finalName>
</build>
</project>
CXF+Spring+Hibernate 实现 RESTful webservice 服务端示例
1. RESTful API 接口定义
/* * Copyright 2016-2017 WitPool.org All Rights Reserved. * * You may not use this file except in compliance with the License. * A copy of the License is located at * http://www.witpool.org/licenses * * or in the "license" file accompanying this file. This file is distributed * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.witpool.rest; import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import org.witpool.common.model.bean.WitEntity; import org.witpool.common.model.po.WitAccount; /** * @ClassName: IWitAccount * @Description: Account service definition * @author Dom Wang * @date 2017-11-11 AM 11:21:55 * @version 1.0 */ @Path("/account") public interface IWitAccount { /** * * * @Title: addAccount * @Description: Add account * @param @param account * @param @return * @return WitEntity<WitAccount> * @throws */ @POST WitEntity<WitAccount> addAccount(WitAccount account); /** * * * @Title: updateAccount * @Description: Update account * @param @param account * @param @return * @return WitEntity<WitAccount> * @throws */ @PUT WitEntity<WitAccount> updateAccount(WitAccount account); /** * * * @Title: delAccount * @Description: Delete account by user ID * @param @param userId * @param @return * @return WitEntity<WitAccount> * @throws */ @DELETE @Path("/{userId}") WitEntity<WitAccount> delAccount(@PathParam("userId") Integer userId); /** * * * @Title: getAccount * @Description: Query account by user ID * @param @param userId * @param @return * @return WitEntity<WitAccount> * @throws */ @GET @Path("/{userId}") WitEntity<WitAccount> getAccount(@PathParam("userId") Integer userId); /** * * * @Title: getAccount * @Description: Query all the accounts * @param @param userId * @param @return * @return WitEntity<WitAccount> * @throws */ @GET @Path("/all") WitEntity<WitAccount> getAccounts(); }
2. CXF 与 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" xmlns:jaxrs="http://cxf.apache.org/jaxrs" xmlns:cxf="http://cxf.apache.org/core" xmlns:util="http://www.springframework.org/schema/util" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd"> <import resource="classpath*:META-INF/cxf/cxf.xml"/> <import resource="classpath*:META-INF/cxf/cxf-servlet.xml"/> <import resource="classpath:persist-config.xml"/> <jaxrs:server id="witpool" address="/"> <jaxrs:inInterceptors> <bean class="org.apache.cxf.interceptor.LoggingInInterceptor"/> </jaxrs:inInterceptors> <jaxrs:outInterceptors> <bean class="org.apache.cxf.interceptor.LoggingOutInterceptor"/> </jaxrs:outInterceptors> <jaxrs:providers> <ref bean="jacksonProvider"/> </jaxrs:providers> <jaxrs:extensionMappings> <entry key="json" value="application/json"/> <entry key="xml" value="application/xml"/> </jaxrs:extensionMappings> <jaxrs:serviceBeans> <ref bean="witAccount"/> </jaxrs:serviceBeans> </jaxrs:server> <bean id="jaxbAnnotationIntrospector" class="com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector"/> <bean id="jsonmapper" class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean" p:annotationIntrospector-ref="jaxbAnnotationIntrospector"> <property name="featuresToEnable"> <array> <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.INDENT_OUTPUT"/> <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_DATES_AS_TIMESTAMPS"/> </array> </property> <property name="featuresToDisable"> <array> <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_NULL_MAP_VALUES"/> <util:constant static-field="com.fasterxml.jackson.databind.SerializationFeature.WRITE_EMPTY_JSON_ARRAYS"/> </array> </property> <property name="objectMapper"> <bean class="com.fasterxml.jackson.databind.ObjectMapper"></bean> </property> </bean> <bean id="jacksonProvider" class="com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider"> <property name="mapper" ref="jsonmapper"/> </bean> <bean id="witAccount" class="org.witpool.rest.impl.WitAccountImpl"/> </beans>
3.Spring 与 Hibernate 的集成配置
<?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd "> <!-- Scan Bean --> <context:component-scan base-package="org.witpool.common.model.po"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:resources.properties</value> </list> </property> </bean> <bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource"> <property name="alias" value="proxoolDataSource"/> <property name="driver" value="${connection.driver_class}"/> <property name="driverUrl" value="${connection.url}"/> <property name="user" value="${connection.username}"/> <property name="password" value="${connection.password}"/> <property name="maximumConnectionCount" value="${proxool.maximum.connection.count}"/> <property name="minimumConnectionCount" value="${proxool.minimum.connection.count}"/> <property name="statistics" value="${proxool.statistics}"/> <property name="simultaneousBuildThrottle" value="${proxool.simultaneous.build.throttle}"/> </bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="packagesToScan"> <list> <value>org.witpool.common.model.po</value> </list> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.query.substitutions">${hibernate.query.substitutions}</prop> <prop key="hibernate.default_batch_fetch_size">${hibernate.default_batch_fetch_size}</prop> <prop key="hibernate.max_fetch_depth">${hibernate.max_fetch_depth}</prop> <prop key="hibernate.generate_statistics">${hibernate.generate_statistics}</prop> <prop key="hibernate.bytecode.use_reflection_optimizer">${hibernate.bytecode.use_reflection_optimizer}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.bytecode.use_reflection_optimizer}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> </props> </property> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <aop:config> <aop:pointcut id="rest-api" expression="execution(* org.witpool.rest.*.*(..))"/> <aop:advisor pointcut-ref="rest-api" advice-ref="txAdvice"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="find*" read-only="false" propagation="NOT_SUPPORTED"/> <tx:method name="query*" read-only="false" propagation="NOT_SUPPORTED"/> <tx:method name="get*" read-only="false" propagation="NOT_SUPPORTED"/> <tx:method name="add" propagation="REQUIRED"/> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="save" propagation="REQUIRED"/> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <bean id="baseDao" class="org.witpool.persist.dao.impl.BaseDaoImpl"> <property name="sessionFactory" ref="sessionFactory"/> <property name="baseDao" ref="baseDao"/> </bean> </beans>
4.Hibernate 的参数配置
hibernate.dialect=org.hibernate.dialect.MySQLDialect hibernate.hbm2ddl.auto=update hibernate.show_sql=true hibernate.query.substitutions=true 1, false 0 hibernate.default_batch_fetch_size=16 hibernate.max_fetch_depth=2 hibernate.bytecode.use_reflection_optimizer=true hibernate.cache.use_second_level_cache=true hibernate.cache.use_query_cache=true hibernate.cache.region.factory_class=org.hibernate.cache.EhCacheRegionFactory net.sf.ehcache.configurationResourceName=/ehcache_hibernate.xml hibernate.cache.use_structured_entries=true hibernate.generate_statistics=true connection.driver_class=com.mysql.jdbc.Driver connection.url=jdbc:mysql://localhost:3306/witpool?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=gbk&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true connection.username=root connection.password=123456 proxool.maximum.connection.count=40 proxool.minimum.connection.count=5 proxool.statistics=1m,15m,1h,1d proxool.simultaneous.build.throttle=30
5. 代码下载、编译、打包
代码下载请访问 GitHub 上的 witpool/wit-pluto
导入工程文件、编译、打包步骤如下:
6. 部署和 UT 步骤
将编译生成的包 wit-rest.war
复制到 Tomcat 8.5\webapps\
, 重启 tomcat
UT 步骤:
(1). 下载 Wisdom REST Client
(2). 双击 JAR 包 restclient-1.1.jar
启动工具
导入测试用例文件:
关于 Wisdom REST Client 更多的使用帮助,请参考博客。
java – Spring:文件上传RESTFUL Web Service
如果我们只传递String或任何其他基本数据,它可以正常工作.
@RequestMapping(value="/getcontent/file",method=RequestMapping.post) public String getFileContents(@RequestParam("fileName",required=false) String fileName){ logger.info("initialization of object"); //---------------------------------------- System.out.Println("name of File : " + fileName); //---------------------------------------- }
这工作正常
但是如果我要传递字节流或文件对象功能,那么我可以用这些参数来写这个函数吗?并且我如何写客户端提供传递字节流?
@RequestMapping(value="/getcontent/file",method=RequestMapping.post) public String getFileContents(@RequestParam("file",required=false) byte [] fileName){ //--------------------- // }
我试过这个代码,但是得到415错误.
@RequestMapping(value = "/getcontent/file",method = RequestMethod.POST,consumes="multipart/form-data") public @ResponseBody String getContentFromBytes(@RequestBody MultipartFormDataInput input,Model model) { logger.info("Get Content. "); //------------ }
客户端代码 – 使用apache HttpClient
private static void executeClient() { HttpClient client = new DefaultHttpClient(); HttpPost postReqeust = new HttpPost(SERVER_URI + "/file"); try{ // Set VarIoUs Attributes multipartentity multipartentity = new multipartentity(); multipartentity.addPart("fileType",new StringBody("DOCX")); FileBody fileBody = new FileBody(new File("D:\\demo.docx"),"application/octect-stream"); // prepare payload multipartentity.addPart("attachment",fileBody); //Set to request body postReqeust.setEntity(multipartentity); HttpResponse response = client.execute(postReqeust) ; //Verify response if any if (response != null) { System.out.println(response.getStatusLine().getStatusCode()); } } catch(Exception ex){ ex.printstacktrace(); }
解决方法
@RequestMapping(value="/upload",method=RequestMethod.POST) public @ResponseBody String handleFileUpload( @RequestParam("file") multipartfile file){ String name = "test11"; if (!file.isEmpty()) { try { byte[] bytes = file.getBytes(); bufferedoutputstream stream = new bufferedoutputstream(new FileOutputStream(new File(name + "-uploaded"))); stream.write(bytes); stream.close(); return "You successfully uploaded " + name + " into " + name + "-uploaded !"; } catch (Exception e) { return "You Failed to upload " + name + " => " + e.getMessage(); } } else { return "You Failed to upload " + name + " because the file was empty."; } }
而客户端做如下.
import java.io.File; import org.apache.http.httpentity; import org.apache.http.HttpResponse; import org.apache.http.HttpVersion; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.mime.multipartentity; import org.apache.http.entity.mime.content.ContentBody; import org.apache.http.entity.mime.content.FileBody; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.CoreProtocolPNames; import org.apache.http.util.EntityUtils; public class Test { public static void main(String[] args) throws Exception { HttpClient httpclient = new DefaultHttpClient(); httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,HttpVersion.HTTP_1_1); HttpPost httppost = new HttpPost("http://localhost:8080/upload"); File file = new File("C:\\Users\\Kamal\\Desktop\\PDFServlet1.pdf"); multipartentity mpEntity = new multipartentity(); ContentBody cbFile = new FileBody(file,"multipart/form-data"); mpEntity.addPart("file",cbFile); httppost.setEntity(mpEntity); System.out.println("executing request " + httppost.getRequestLine()); HttpResponse response = httpclient.execute(httppost); httpentity resEntity = response.getEntity(); System.out.println(response.getStatusLine()); if (resEntity != null) { System.out.println(EntityUtils.toString(resEntity)); } if (resEntity != null) { resEntity.consumeContent(); } httpclient.getConnectionManager().shutdown(); } }
关于Spring 4.x实现Restful web service和spring的restful的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于Apache CXF 和 Spring 开发RESTful Web Service 2、CXF 结合 spring 发布 WS 服务,含 SOAP services、RESTful services、CXF+Spring+Hibernate 实现 RESTful webservice 服务端示例、java – Spring:文件上传RESTFUL Web Service等相关内容,可以在本站寻找。
本文标签: