GVKun编程网logo

Spring 4.x实现Restful web service(spring的restful)

16

这篇文章主要围绕Spring4.x实现Restfulwebservice和spring的restful展开,旨在为您提供一份详细的参考资料。我们将全面介绍Spring4.x实现Restfulwebse

这篇文章主要围绕Spring 4.x实现Restful web servicespring的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)

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

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

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<AddressgetSuggestions(@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 服务端示例

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
导入工程文件、编译、打包步骤如下:
导入工程文件选择Existing Maven Projects
指定要导入的Maven工程的根目录路径
选择主工程 wit-pluto 运行maven install
在wit-rest的target目录下获取wit-rest.war

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

java – Spring:文件上传RESTFUL Web Service

我正在使用 Spring 4.0为RESTFUL Web服务创建POC.
如果我们只传递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 servicespring的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等相关内容,可以在本站寻找。

本文标签: