[Webservice基础]-- java使用idea、dubbox、cxf构建web service
使用dubbox构建web service开发环境:windows 8.1 +maven 3.3.9+idea 16.1 +jdk 1.7+dubbox 2.8.4+zookeeper3.4.6 + tomcat 8搭建步骤:一、环境准备 1、安装jdk1.7、idea 16、tomcat8(我使用的发布dubbox的方式是tomcat,其他方式参考: ...
使用dubbox构建web service
开发环境:windows 8.1 +maven 3.3.9+idea 16.1 +jdk 1.7+dubbox 2.8.4+zookeeper3.4.6 + tomcat 8
搭建步骤:
一、环境准备
1、安装jdk1.7、idea 16、tomcat8(我使用的发布dubbox的方式是tomcat,其他方式参考:
http://dangdangdotcom.github.io/dubbox/rest.html)、zookeeper单节点(集群也可以)
2、安装本地maven、下载dubbox最新源码包(https://github.com/dangdangdotcom/dubbox)
3、确认jdk、idea、maven安装成功后,配置idea、jdk、tomcat以及maven的关联;
再将下载的dubbox-master解压后导入idea中,然后单击项目,右键 使用maven reimport,重新构建dubbox项目
4、构建项目完成后(需要2h左右),dos命令行进入dubbox-master的目录下,执行mvn clean install -Dmaven.test.skip;
等待mvn编译生成有结构的jar包,jar包的目录是你本地maven库的根目录:
二、开始开发(确保以上环境都已经安装和配置成功)
1、打开idea16、新建一个web app的maven项目:dubbox-restful
同时修改目录结构:
2、将编译好的dubbox包(alibaba)放在maven库的com目录下(或者不改变路径,直接修改pom.xml引入,但是本人不推荐使用)。
3、pom.xml中引入相关的依赖包,pom内容如下:
<projectxmlns="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>dubbox-restful</groupId>
<artifactId>com.webservice</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>com.webservice Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.7</java.version>
<!--add maven release-->
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
<encoding>UTF-8</encoding>
</properties>
<dependencies>
<!-- dubbox -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.8.4</version>
</dependency>
<!-- cxf -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>3.0.0-milestone1</version>
</dependency>
<!--zookeeper-->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.6</version>
</dependency>
<!-- jetty -->
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.26</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxrs</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-client</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>1.0.0.GA</version>
</dependency>
<!-- 如果要使用json序列化 -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jackson-provider</artifactId>
<version>3.0.7.Final</version>
</dependency>
<!-- 如果要使用xml序列化 -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-jaxb-provider</artifactId>
<version>3.0.7.Final</version>
</dependency>
<!-- 如果要使用netty server -->
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-netty</artifactId>
<version>3.0.7.Final</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.2</version>
</dependency>
<!-- zookeeper -->
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.3.6</version>
<exclusions>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- log -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<!--gson-->
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>com.webservice</finalName>
</build>
</project>
4、编写代码,目录结构如下:
文件bean结构中的内容依次如下:
(1)GsonInfo.java
package enn.bean;
import java.io.Serializable;
/**
* Document:本类作用---->解析json字符串
* User: yangjf
* Date: 2016/7/17 19:59
*/
public class GsonInfoimplementsSerializable{
private String id;
private String name;
public GsonInfo(){}
public GsonInfo(String id, String name) {
this.id= id;
this.name= name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id= id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name= name;
}
@Override
publicString toString() {
return "GsonInfo{"+
"id='" +id+ '\''+
", name='" +name+ '\''+
'}';
}
}
(2)MessageInfo.Java
package enn.bean;
import java.io.Serializable;
/**
* Document:本类作用---->
* User: yangjf
* Date: 2016/7/17 20:17
*/
public class MessageInfoimplementsSerializable {
private GsonInfo message;
public MessageInfo(){}
public MessageInfo(GsonInfo message) {
this.message= message;
}
public GsonInfo getMessage() {
return message;
}
public void setMessage(GsonInfo message) {
this.message= message;
}
@Override
publicString toString() {
return "MessageInfo{"+
"message=" +message+
'}';
}
}
(3)ResultInfo.java
package enn.bean;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
/**
* Document:本类作用---->返回给客户端的结果类
* User: yangjf
* Date: 2016/7/17 18:06
* 注意:必需添加@XmlRootElement注解和序列化,否则GET方法返回值为空
*/
@XmlRootElement
public class ResultInfoimplementsSerializable{
private String result;//该名称是返回的gson串的一个key
privateStringstatus;//该名称是返回的gson串的一个key
publicResultInfo(){}
public ResultInfo(String result, String status) {
this.result= result;
this.status= status;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result= result;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status= status;
}
}
service结构中的类如下:
(1)接口类:IUserService.java
package enn.service.interfaces;
import enn.bean.ResultInfo;
import javax.ws.rs.QueryParam;
/**
* Document:本类作用---->测试用户访问的接口类
* User: yangjf
* Date: 2016/7/17 18:03
*/
public interface IUserService {
/**获取信息,注解代表请求的参数名称*/
publicResultInfo getUserInfo(@QueryParam("id")String id,@QueryParam("name")String name)throwsException;
/**实现POST请求*/
//由于Post方法不需要添加@QueryParam,
// 所以如果添加了@QueryParam会导致空指针异常,message名称可以任意取名,但是要和实现类中一致
publicResultInfo getPostUserInfo(String message)throwsException;
}
(2)实现类:IUserServiceImpl.java
package enn.service.impl;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import enn.bean.GsonInfo;
import enn.bean.MessageInfo;
import enn.bean.ResultInfo;
import enn.service.interfaces.IUserService;
import javax.ws.rs.*;
/**
* Document:本类作用---->查询的实现类
* User: yangjf
* Date: 2016/7/17 18:11
*/
@Path("/services/user")/**一级访问目录*/
public class IUserServiceImplimplementsIUserService {
@GET
@Path("getUser")/**二级访问目录*/
// @Produces({"application/json;charset=UTF-8"})/**指定返回值类型是json格式*/
@Produces({"text/xml;charset=UTF-8"})/**指定返回值类型是xml格式格式*/
publicResultInfo getUserInfo(@QueryParam("id") String id,@QueryParam("name") String name)throwsException {
ResultInfo resultInfo=new ResultInfo(id,name);
try{
System.out.println("id:"+id);
System.out.println("name:"+name);
}catch(Exception e){
e.printStackTrace();
resultInfo=new ResultInfo("123456","cassie");
}
return resultInfo;/**如果指定xml格式返回值,那么该名称即是xml的头文件表签名称*/
}
@POST
@Path("/getPostuser")
@Produces({"application/json;charset=UTF-8"})
public ResultInfo getPostUserInfo(String message)throwsException {
System.out.println("获取到的message:"+message);
GsonBuilder gb=new GsonBuilder();
Gson gson=gb.create();
MessageInfo gsonInfo=gson.fromJson(message,MessageInfo.class);
ResultInfo resultInfo=new ResultInfo(gsonInfo.getMessage().getId(),gsonInfo.getMessage().getName());
return resultInfo;
}
}
resource结构中的配置文件:
(1)dubbo-server-restful.xml(注意:spring的配置文件中的空格不能去掉!!)
<?xml version="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系,主要用于dubbox内部消费时使用 -->
<dubbo:applicationname="hello-user"/>
<!-- zookeeper注册地址,可以是列表,以逗号分割: -->
<dubbo:registryaddress="zookeeper://192.168.1.101:2181"/>
<!--<dubbo:provider protocol="webservice" />-->
<!-- 用dubbo协议在端口暴露服务,端口可以按规则任意指定 -->
<dubbo:protocolname="rest" port="9000"/>
<!-- 声明需要暴露的服务接口 -->
<dubbo:serviceprotocol="rest"interface="enn.service.interfaces.IUserService"ref="userService"/>
<!-- 和本地bean一样实现服务 -->
<beanid="userService"class="enn.service.impl.IUserServiceImpl"/>
</beans>
(2)log4j.properties
log4j.rootLogger=INFO,console
#log4j.additivity.org.apache=true
# console
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Threshold=WARN
log4j.appender.console.ImmediateFlush=true
log4j.appender.console.Target=System.err
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-5p] %d %m %x %n
test目录结构文件内容
(1)HttpUrlTest.java测试get/post请求的类
package services;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.junit.Test;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import static javax.ws.rs.core.MediaType.APPLICATION_JSON;
/**
* Document:本类作用---->访问web service(get和post方式)
* User: yangjf
* Date: 2016/7/17 18:27
*/
public class HttpUrlTest {
/**测试get方式请求url*/
@Test
public voidtestGet() {
String urlString="http://localhost:9000/services/user/getUser?id=12&name=lisi";
BufferedReader br=null;
try{
//创建url请求
URL url=newURL(urlString);
//连接请求协议
HttpURLConnection _url=(HttpURLConnection)url.openConnection();
//设置请求方法
_url.setRequestMethod("GET");
//设置请求开启连接
_url.connect();
//写入请求参数,记得把字节流转换成字符流
br=newBufferedReader(newInputStreamReader(_url.getInputStream()));//_url.getInputStream()是URL返回的流
//实现读入内存的操作
String content="";
StringBuffer ss=new StringBuffer();
while((content=br.readLine())!=null){
ss.append(content);
}
System.out.println(ss.toString());
}catch(Exception e){
throw new RuntimeException(e);
}finally{
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**测试Post方式请求Url*/
@Test
public voidtestPost()throwsException{
String APPLICATION_JSON = "application/json";
String CONTENT_TYPE_TEXT_JSON = "text/json";
String urlPost="http://localhost:9000/services/user/getPostuser";
String json="{\"message\":{\"id\":\"001\",\"name\":\"guo\"}}";
// 将JSON进行UTF-8编码,以便传输中文
String encoderJson = URLEncoder.encode(json, HTTP.UTF_8);
// String encoderJson = json;
DefaultHttpClient httpClient =newDefaultHttpClient();
HttpPost httpPost = new HttpPost(urlPost);
httpPost.addHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON);
StringEntity se = new StringEntity(encoderJson);
se.setContentType(CONTENT_TYPE_TEXT_JSON);//请求内容格式
se.setContentEncoding(newBasicHeader(HTTP.CONTENT_TYPE, APPLICATION_JSON));
httpPost.setEntity(se);
HttpResponse response = httpClient.execute(httpPost);
String result= EntityUtils.toString(response.getEntity());
System.out.println("返回结果:"+result);
}
}
(2)TestGson.java生成json的类
package services;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import enn.bean.GsonInfo;
import enn.bean.MessageInfo;
/**
* Document:本类作用---->测试生成json串
* User: yangjf
* Date: 2016/7/17 20:04
*/
public class TestGson {
public static void main(String[] args) {
GsonInfo gin=new GsonInfo("001","guo");
MessageInfo ms=new MessageInfo(gin);
GsonBuilder gb=new GsonBuilder();
Gson gson=gb.create();
System.out.println(gson.toJson(ms));//{"message":{"id":"001","name":"guo"}}
}
}
(3)httpTest :httpclient方式调用webservice(get方式)
package services;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import java.io.IOException;
import java.io.InputStream;
/**
* httpclient方式调用webservice(get方式)
*/
public class httpTest {
public static void main(String[] args)throwsClientProtocolException, IOException {
//访问的url
HttpGet get = new HttpGet("http://localhost:9000/services/user/getUser?id=12&name=lisi");
HttpClient httpclient = new DefaultHttpClient();
get.addHeader("ACCEPT","text/xml");// 如果指定返回值是json:get.addHeader("ACCEPT", "application/json");
HttpResponse response = httpclient.execute(get);
//获取返回值
InputStream ins = response.getEntity().getContent();
byte[] b = new byte[1024];
StringBuilder sb = new StringBuilder();
while (ins.read(b) != -1) {
sb.append(new String(b,"UTF-8"));
}
System.out.println("返回值内容:"+sb.toString());
}
}
web.xml文件配置
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 定义资源访问路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:demo/dubbo-server-restful.xml</param-value>
</context-param>
<!--spring的配置-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--dubbo 服务根路径-->
<servlet>
<servlet-name>dubbo</servlet-name>
<servlet-class>com.alibaba.dubbo.remoting.http.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dubbo</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
三、Tomcat运行web service,实现访问
1、添加项目到tomcat
启动zookeeper------>再启动tomcat
如果发现以下内容,说明启动成功,可以访问了。
四、测试访问web service(浏览器和java代码访问)
1、火狐rest client访问
(1)get方式
(2)post方式
2、java 代码实现请求(get和post)
(1)get方式
执行HttpUrlTest.java中的 public voidtestGet() 方法
(2)Post方式
执行HttpUrlTest.java中的public voidtestPost()方法
可能遇到的问题:
1、Get方式url访问报错:
浏览器输入:http://localhost:9000/services/user/getUser?id=12&name=lisi
错误:Could not find MessageBodyWriter for response object of type:
enn.bean.ResultInfo of media type: text/xml;charset=UTF-8
解决:在返回对象类中添加注解@XmlRootElement即可解决
2、POST方式请求报空指针异常
注意:需要在火狐中添加restClient,然后
Post请求需要添加请求头:
Accept = application/json
Content-Type = application/json;charset=UTF-8
Body中添加:{"message":{"id":"001","name":"guo"}}
另一种问题解决:
以上测试已经通过,可以按自己的需求进行更改;如有疑问,请留言。
更多推荐
所有评论(0)