最近涉及到用Jersey RESTful 的WebService框架,抽空把这段时间的要点整理成了一篇博文。
一 .常用的接口框架
不同于我们知道的Java接口(interface),此处的接口是指我们的远程调用接口。通过调用远程接口达到调用服务或者请求数据等目的。
通常我们的接口调用方式一般有三种:先粗略的过一遍。
1.HttpClient
HttpClient是基于HTTP 协议的客户端连接方式,以此基础完成各种接口交互。
Http是一种无状态协议,所谓无状态就是无上下文,一次请求就是一次,非连续。要知道之前做了什么,需要读取相关的参数才行。
注意,这里要和TCP的三次握手区分开!
2.WebSocket
同样基于TCP的底层传输,使用websocket,但是要知道 websocket基于 HTTP 协议设计,刚开始仍然是HTTP连接,后面才转换为Socket通道。
这里一开始仍然是使用Http,然后确定建立socket通道后才关闭http、
我们粗略的了解一下webscoket的工作原理:
注意,webScoket通常是基于Tomcat或者netty等web容器来创建,或者说将socket搭建在容器上面,通过相关的类和提供的jar来控制。
3.webService
这一篇的主要内容就是webService,下面开始详细的说明一下。
二.WebService
1.webService架构
(图片来源:http://dyygusi.iteye.com/blog/2148029)
webservice就是远程调用技术,也叫XML Web Service WebService是一种可以接收从Internet或者Intranet上的其它系统中传递过来的请求,轻量级的独立的通讯技术。是:通过SOAP在Web上提供的软件服务,使用WSDL文件进行说明,并通过UDDI进行注册。
名词 全称 解析
XML (Extensible Markup Language)扩展型可标记语言 面向短期的临时数据处理、面向万维网络,是Soap的基础。
Soap (Simple Object Access Protocol)简单对象存取协议 是XML Web Service 的通信协议。当用户通过UDDI找到你的WSDL描述文档后,他通过可以SOAP调用你建立的Web服务中的一个或多个操作。SOAP是XML文档形式的调用方法的规范,它可以支持不同的底层接口,像HTTP(S)或者SMTP。
WSDL (Web Services Description Language) WSDL 文件是一个 XML 文档,用于说明一组 SOAP 消息以及如何交换这些消息。大多数情况下由软件自动生成和使用
UDDI 通用描述、发现与集成服务 一种规范,它主要提供基于Web服务的注册和发现机制,为Web服务提供三个重要的技术支持:①标准、透明、专门描述Web服务的机制;②调用Web服务的机制;③可以访问的Web服务注册中心。
以上的流程是基础流程,通常不需要这些,我们会基于框架完成webservice.
贴一下JSR-181的注解。(这是一个实现规范)
来源:https://www.cnblogs.com/zhao-shan/p/5515174.html
@WebService:标注webservice接口
参数 作用
serviceName 对外发布的服务名,指定 Web Service 的服务名称,缺省值为 Java 类的简单名称 + Service。
endpointInterface 服务接口全路径, 指定做SEI(Service EndPoint Interface)服务端点接口
name 此属性的值包含XML Web Service的名称。在默认情况下,该值是实现XML Web Service的类的名称,wsdl:portType 的名称。缺省值为 Java 类或接口的非限定名称。(字符串)
portName wsdl:portName。缺省值为 WebService.name+Port。
targetNamespace 指定你想要的名称空间,认是使用接口实现类的包名的反缀
wsdlLocation 指定用于定义 Web Service 的 WSDL 文档的 Web 地址。Web 地址可以是相对路径或绝对路径。(字符串)
@WebMethod :注释表示作为一项 Web Service 操作的方法,将此注释应用于客户机或服务器服务端点接口(SEI)上的方法,或者应用于 JavaBeans 端点的服务器端点实现类。
参数 作用
operationName 指定与此方法相匹配的wsdl:operation 的名称。缺省值为 Java 方法的名称。(字符串)
action 定义此操作的行为。对于 SOAP 绑定,此值将确定 SOAPAction 头的值。缺省值为 Java 方法的名称。(字符串)
exclude 指定是否从 Web Service 中排除某一方法。缺省值为 false。(布尔值)
@Oneway :注释将一个方法表示为只有输入消息而没有输出消息的 Web Service 单向操作。将此注释应用于客户机或服务器服务端点接口(SEI)上的方法,或者应用于 JavaBeans 端点的服务器端点实现类
@WebParam :注释用于定制从单个参数至 Web Service 消息部件和 XML 元素的映射。
参数 作用
name 参数的名称。如果操作是远程过程调用(RPC)类型并且未指定partName 属性,那么这是用于表示参数的 wsdl:part 属性的名称。
partName 定义用于表示此参数的 wsdl:part属性的名称。仅当操作类型为 RPC 或者操作是文档类型并且参数类型为BARE 时才使用此参数。(字符串)
targetNamespace 指定参数的 XML 元素的 XML 名称空间。当属性映射至 XML 元素时,仅应用于文档绑定。缺省值为 Web Service 的 targetNamespace。(字符串)
mode 此值表示此方法的参数流的方向。有效值为 IN、INOUT 和 OUT。(字符串)
header 指定参数是在消息头还是消息体中。缺省值为 false。(布尔值)
@WebResult : 注释用于定制从返回值至 WSDL 部件或 XML 元素的映射。将此注释应用于客户机或服务器服务端点接口(SEI)上的方法,或者应用于 JavaBeans 端点的服务器端点实现类。
参数 作用
name 当返回值列示在 WSDL 文件中并且在连接上的消息中找到该返回值时,指定该返回值的名称。
targetNamespace 指定返回值的 XML 名称空间。
header 指定头中是否附带结果。缺省值为false。(布尔值)
partName 指定 RPC 或 DOCUMENT/BARE 操作的结果的部件名称。缺省值为@WebResult.name。(字符串)
三.jersey restful
Restful接口学习笔记
框架:Jersey架构,Maven管理
前言:个人认为restful总体上采用的是MVC架构思想,但是Jersey这个框架体现的不明显。所以我在我的代码中模块逻辑操作处理(相当于代码中的resource文件夹),还有控制块数据操作处理(即代码中的server文件夹)完全分成两部分。而MVC架构中的视图部分由于没有需求暂时没有开发。REST 是一种架构原则,其中将 web 服务视为资源,可以由其 URL 唯一标识。RESTful Web 服务的关键特点是明确使用 HTTP 方法来表示不同的操作的调用。
创建一个helloworld Maven工程:
l 使用工程根目录下的pox.xml文件实现工程的建立和配置管理
l 工程资源被加载在src/main/java中
下面这个在com.example包中的类就是资源类,实现了一个简单的JAX-RS资源:
package com.example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path(“helloworld”) //标记该资源的路径
public class HelloWorldResource {
@GET //使用HTTP GET操作方法
@Produces(“text/plain”) //以text/plain类型发送给客户端
public String getHello() {
return “Hello World!”;
}
}
资源加载器:
public class MyApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet
Jersey架构和Maven工程的一些相关知识:
ujersey常用注解解释(这里只是到现在为止我自己的项目里用到过的):
Annotation 作用 说明
@GET 查询请求 相当于数据库的查询数据操作
@POST 插入请求 相当于数据库的插入数据操作
@PUT 更新请求 相当于数据库的更新数据操作
@DELETE 删除请求 相当于数据的删除数据操作
@Path url路径 定义资源的访问路径,client通过这个路径访问资源。比如:@Path(“user”)
@Produces 指定返回MIME格式 资源按照指定数据格式返回,可取的值有:MediaType.APPLICATION_XXX。比如:@Produces(MediaType.APPLICATION_XML)
@Consumes 接受指定的MIME格式 只有符合这个参数设置的请求再能访问到这个资源。比如@Consumes(“application/x-www-form-urlencoded”)
@PathParam uri路径参数 写在方法的参数中,获得请求路径参数。比如:@PathParam(“username”) String userName
@QueryParam uri路径请求参数 写在方法的参数中,获得请求路径附带的参数。比如:@QueryParam(“desc”) String desc
@DefaultValue 设置@QueryParam参数的默认值 如果@QueryParam没有接收到值,就使用默认值。比如:@DefaultValue(“description”) @QueryParam(“desc”) String desc
@FormParam form传递的参数 接受表单传递过来的参数。比如:@FormParam(“name”) String userName
@Context 获得一些系统环境信息 通过@Context可以获得以下信息:UriInfo、ServletConfig、ServletContext、HttpServletRequest、HttpServletResponse和HttpHeaders等
upom.xml文件配置:
使用Maven工具管理工程非常的方便,相关的配置只需要修改pom.xml文件就可以轻松办到,看下面的例子
设置组ID、artifactID和版本号:
com
VIID
V5
设置打包类型:
war
设置第三方包下载路径:
com.sdk Maven Webapp
http://maven.apache.org
添加需要的依赖包:
org.glassfish.jersey.media
jersey-media-multipart
2.23.2
相关依赖包查询网址:http://maven.outofmemory.cn/或者http://mvnrepository.com/或其它。
当需要添加新的依赖库时,只需要查到相关的依赖库ID和版本号,将其添加到pom.xml中点击Maven Projects下的刷新按钮,Maven工具会自动下载。
添加额外的配置文件或者其它资源:
src/main/resource
/*.xml
/.properties
**/.cfg
false
这个可以将src/main/resource下文件一同编译进classes文件下方便调用
添加插件:
org.mortbay.jetty
maven-jetty-plugin
6.1.26
加入jetty插件,方便程序调试
将pom.xml全部配置好后记得点击刷新按钮。
u web.xml配置:
这个文件主要用来配置Jersey Servlet
<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”>
VIID.MyApplication
org.glassfish.jersey.servlet.ServletContainer
<!-- 配置自己的资源加载类去加载资源 -->
<init-param>
param-name>javax.ws.rs.Application</param-name>
<param-value>VIID.MyApplication</param-value>
</init-param>
<!-- 配置默认的资源包路径,使用默认的配置类去加载资源 -->
<load-on-startup>1</load-on-startup>
VIID.MyApplication /* 以上的VIID.MyApplication为自己写好的资源加载器,个人喜欢这一种方式加载自己想要加载的资源,可控性强。接下来介绍这个资源加载器如何编写。
u 资源加载器编写:
public class MyApplication extends ResourceConfig {
public MyApplication() {
// 加载resources
register(HelloResource.class);
register(UserResource.class);
// 注册数据转换器
register(JacksonJsonProvider.class);
// 注册日志
register(LoggingFilter.class);
}
}
当然,如果觉得把自己写的资源一个一个使用register()方法注册上去太麻烦,也可以像之前讲的一样,把所有资源放在VIID.resource文件夹里,统一注册:
public MyApplication() {
/** 注册资源 */
packages(“VIID.resource”);
register(LoggingFeature.class);
register(MultiPartFeature.class);
register(JacksonJsonProvider.class);
property(JsonGenerator.PRETTY_PRINTING, true);
}
u 编写自己的资源:
@Path(“helloworld”) //标记该资源的路径
public class HelloWorldResource {
@GET //使用HTTP GET操作方法
@Produces(“text/plain”) //以text/plain类型发送给客户端
public String getHello() {
return “Hello World!”;
}
}
接下来是一些注解的使用方法(参照前文的Jersey常用注释解释表格):
@Path(“user”)
public class UserResource {
//这个类的方法都在下面
//这个方法主要介绍@GET,@Path,@Produces,@PathParam,@DefaultValue,@QueryParam注解的使用
@GET
@Path("{username}")
@Produces(MediaType.APPLICATION_JSON)
public User getUser(@PathParam(“username”) String userName,
@DefaultValue(“description”) @QueryParam(“desc”) String desc) {
User user = new User();
user.setId(new Random().nextInt());
user.setUserName(userName);
user.setDesc(desc);
return user;
}
//访问URL:{host}:{port}/{serviceName}/user/username?desc=xxx;username可以随便写
//这个方法主要介绍@POST,@Consumes,@FormParam,@Context注解的使用
@POST
@Path("updateUser")
@Consumes("application/x-www-form-urlencoded")
publicString updateUser(@FormParam("name") String userName,
@FormParam("desc") String desc,
@Context HttpHeaders headers) {
String token =
headers.getRequestHeader(HttpHeaders.AUTHORIZATION).get(0);
User user = new User();
user.setId(1);
user.setUserName(userName);
user.setDesc(desc);
System.out.println(user + access_token);
return token;
//访问URL:{host}:{port}/{serviceName}/user/updateUser;这个是通过提交表单访问的
}
}
完成以上这些,restful接口工程基本可以建立并使用了。
u Jersey客户端代码编写示例:
public static String path = “http://localhost:8080/VIID/”;
public static void test(){
ClientConfig cc = new DefaultClientConfig();
Client client = Client.create(cc);
WebResource resource = client.resource(path + "gethello");
JSONObject req = new JSONObject();
try {
req.put("name", "Jake");
} catch (JSONException e) {
e.printStackTrace();
}
ClientResponse response = resource
.header(HttpHeaders.AUTHORIZATION, "AGHJ3ad") //给http请求数据头中的AUTHORIZATION域加入数据
.accept(MediaType.APPLICATION_JSON) //设定接收数据为JSON格式
.type("application/json") //设定发送数据为JSON格式
.post(ClientResponse.class, req); //使用post请求,请求参数为req
JSONObject resp = response.getEntity(JSONObject.class); //获得服务器返回数据
System.out.println(resp.toString());
}
构建QueryParam参数:
MultivaluedMapImpl params = new MultivaluedMapImpl();
params.add("desc ", s);
ClientResponse response = resource.queryParams(params)
.header(HttpHeaders.AUTHORIZATION, UserLoginCode)
.get(ClientResponse.class);
构建表单:
FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
formDataMultiPart.field(“filename”, “008”);
表单中加入文件:
FileDataBodyPart fdp = new FileDataBodyPart(“file”, new File(filename));
FormDataMultiPart formDataMultiPart = newFormDataMultiPart();
formDataMultiPart.field(“filename”, “008”)
.bodyPart(fdp);ClientResponse response = resource
.type(MediaType.MULTIPART_FORM_DATA)
.post(ClientResponse.class, formDataMultiPart);
pom.xml client依赖库:
com.sun.jersey
jersey-client
1.18.3
u Tomcat部署
首先将整个工程使用IDEA中Jetty插件打包,或者到工程目录下cmd输入命令:
mvn clean package(这个得先建立maven环境变量);
再将编译好的war包放在Tomcat目录中的webapp目录下,重启Tomcat即可。
我这里建议所有调通以后,使用Jerry插件调试,再使用Tomcat部署
(不过有时候Jetty插件和Tomcat默认配置不太一样,所以个别情况下结果会友差别,需要注意)。
————————————————
版权声明:本文为优快云博主「呆萌的我」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/zjutzmh/article/details/52502798
总结
1.参考
http://dyygusi.iteye.com/blog/2148029
https://www.cnblogs.com/yimqiqun/p/WebSocket_demo.html
http://www.cnblogs.com/lyy-2016/p/6388663.html
http://www.iteye.com/topic/1135747
https://www.cnblogs.com/zhao-shan/p/5515174.html
————————————————
版权声明:本文为优快云博主「black-ant」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/zzg19950824/article/details/80300501