第10章 JAX-RS概述

合集下载

Java探索之Feign入门使用详解

Java探索之Feign入门使用详解

Java探索之Feign⼊门使⽤详解⼀,简介Feign使得 Java HTTP 客户端编写更⽅便。

Feign 灵感来源于Retrofit、JAXRS-2.0和WebSocket。

Feign最初是为了降低统⼀绑定Denominator到HTTP API的复杂度,不区分是否⽀持Restful。

Feign旨在通过最少的资源和代码来实现和HTTP API的连接。

通过可定制的解码器和错误处理,可以编写任意的HTTP API。

Maven依赖:<!-- https:///artifact/flix.feign/feign-core --><dependency><groupId>flix.feign</groupId><artifactId>feign-core</artifactId><version>8.18.0</version><scope>runtime</scope></dependency>⼆,为什么选择Feign⽽不是其他你可以使⽤ Jersey 和 CXF 这些来写⼀个 Rest 或 SOAP 服务的java客服端。

你也可以直接使⽤ Apache HttpClient 来实现。

但是 Feign 的⽬的是尽量的减少资源和代码来实现和 HTTP API 的连接。

通过⾃定义的编码解码器以及错误处理,你可以编写任何基于⽂本的 HTTP API。

Feign⼯作机制Feign通过注解注⼊⼀个模板化请求进⾏⼯作。

只需在发送之前关闭它,参数就可以被直接的运⽤到模板中。

然⽽这也限制了Feign,只⽀持⽂本形式的API,它在响应请求等⽅⾯极⼤的简化了系统。

同时,它也是⼗分容易进⾏单元测试的。

三,Feign使⽤简介3.1,基本⽤法基本的使⽤如下所⽰,⼀个对于canonical Retrofit sample的适配。

RESTEasy入门经典

RESTEasy入门经典

RESTEasy是JBoss的开源项目之一,是一个RESTful Web Services框架。

RESTEasy的开发者Bill Burke同时也是JAX-RS的J2EE标准制定者之一。

JAX-RS 是一个JCP制订的新标准,用于规范基于HTTP的RESTful Web Services的API。

我们已经有SOAP了,为什么需要Restful WebServices?用Bill自己的话来说:"如果是为了构建SOA应用,从技术选型的角度来讲,我相信REST比SOAP更具优势。

开发人员会意识到使用传统方式有进行SOA架构有多复杂,更不用提使用这些做出来的接口了。

这时他们就会发现Restful Web Services的光明之处。

"说了这么多,我们使用RESTEasy做一个项目玩玩看。

首先创造一个maven1的web 项目Java代码1.mvn archetype:create -DgroupId=org.bluedash \2.3.-DartifactId=try-resteasy -DarchetypeArtifactId=maven-archetype-webapp准备工作完成后,我们就可以开始写代码了,假设我们要撰写一个处理客户信息的Web Service,它包含两个功能:一是添加用户信息;二是通过用户Id,获取某个用户的信息,而交互的方式是标准的WebService形式,数据交换格式为XML。

假设一条用户包含两个属性:Id和用户名。

那么我们设计交换的XML数据如下:Java代码1.<user>2. <id>1</id>3. <name>liweinan</name>4.</user>首先要做的就是把上述格式转换成XSD2,网上有在线工具可以帮助我们完成这一工作3,在此不详细展开。

使用工具转换后,生成如下xsd文件:Java代码1.<?xml version="1.0" encoding="utf-8"?>2.<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified"3.version="1.0" xmlns:xsd="/2001/XMLSchema">4. <xsd:element name="user" type="userType" />5. <xsd:complexType name="userType">6. <xsd:sequence>7. <xsd:element name="id" type="xsd:int" />8. <xsd:element name="name" type="xsd:string" />9. </xsd:sequence>10. </xsd:complexType>11.</xsd:schema>有了xsd文件,我们便可以使用JDK自带工具的xjc将xsd转换成为Java的Class。

使用Eclipse开发基于SpringBoot+JAX-RS的Restful服务

使用Eclipse开发基于SpringBoot+JAX-RS的Restful服务

一.搭建工程(开发环境JDK1.8,外置Tomcat需8.5以上版本)1.新建maven项目2.修改pom文件,内容如下:<project xmlns="/POM/4.0.0" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/POM/4.0.0 /xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>springboot.jaxrs</groupId><artifactId>RestWS</artifactId><version>0.0.1-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.0.RELEASE</version></parent><dependencies><!-- Web应用依赖:主要用来进行Web应用开发 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><!-- 排除Web依赖提供的Tomcat容器,由下面的Tomcat依赖提供Tomcat容器 --><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><!-- 模板引擎依赖:主要用来提供@Controller和html页面等的访问 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!-- RESTful服务依赖:主要用来提供Jersey RESTful Web服务框架的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jersey</artifactId></dependency><!-- Tomcat容器依赖:主要用来提供编译和测试时的Tomcat支持,打war包时不会包含到lib --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId><scope>provided</scope></dependency><!-- 测试组件依赖:用来提供单元测试的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><!-- 排除JUnit4的包,只引入JUnit5的包 --><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency></dependencies><build><!-- 打包后的文件名 --><finalName>springboot</finalName><plugins><!-- SpringBoot打包插件,指定main方法的类 --><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><mainClass>com.springboot.SpringBootRun</mainClass> </configuration></plugin></plugins></build></project>3.新建一个springboot.jaxrs的包,并建一个SpringBootRun类package springboot.jaxrs;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.builder.SpringApplicationBuilder;importorg.springframework.boot.web.servlet.support.SpringBootServletInitializer;@SpringBootApplicationpublic class SpringBootRun extends SpringBootServletInitializer {//通过外置Tomcat启动SpringBoot项目@Overrideprotected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {// TODO Auto-generated method stubreturn builder.sources(SpringBootRun.class);}//通过内置Tomcat启动SpringBoot项目public static void main(String[] args) {SpringApplication.run(SpringBootRun.class, args);}}4.新建一个RestConfig类package springboot.jaxrs;import javax.ws.rs.ApplicationPath;import org.glassfish.jersey.server.ResourceConfig;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.UrlBasedCorsConfigurationSource; import org.springframework.web.filter.CorsFilter;@Configuration@ApplicationPath("/services")public class RestConfig extends ResourceConfig {//注册服务public RestConfig() {//1.自动扫描com.springboot下面的服务packages("springboot.jaxrs");//2.手动注册服务//register(HelloWorldService.class);//register(TestService.class);System.out.println("WADL地址:http://localhost:8080/RestWS/services/application.wadl");}//添加跨域访问服务:只开放了WS访问,没有开放@Controller访问@Beanpublic CorsFilter corsFilter() {CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();source.registerCorsConfiguration("/ws/**", corsConfiguration); // 4 设置允许访问的地址过滤return new CorsFilter(source);}}5.新建一个springboot.jaxrs.controller的包,并建一个PagesController类package springboot.jaxrs.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.CrossOrigin;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import org.springframework.web.bind.annotation.ResponseBody;@CrossOrigin(origins = "*",maxAge = 3600)//如果想让@Controller允许跨域访问可以加上@CrossOrigin@Controller@RequestMapping("/pages")public class PagesController {@ResponseBody@RequestMapping(value = "/say", method = RequestMethod.GET)public String index() {return"Hello World";}@RequestMapping("/main")public String mainPage() {return"main";}}6.新建一个springboot.jaxrs.entity的包,并新建User类package springboot.jaxrs.entity;public class User {private String name;//姓名private String idNo;//身份证private String password;//密码public User(String name,String idNo,String password) { = name;this.idNo = idNo;this.password = password;}//重写HashCode方法,让程序判断身份证号码相同为同一个对象@Overridepublic int hashCode() {// TODO Auto-generated method stubreturn idNo.hashCode();}//重写equals方法,让程序判断身份证号码相同为同一个对象@Overridepublic boolean equals(Object obj) {// TODO Auto-generated method stubif(obj instanceof User){User user = (User) obj;return this.idNo.equals(user.getIdNo());}else {return false;}}@Overridepublic String toString() {// TODO Auto-generated method stubreturn"[name:"+name+",idNo:"+idNo+",password:"+password+"]";}public String getName() {return name;}public String getIdNo() {return idNo;}public void setIdNo(String idNo) {this.idNo = idNo;}public void setName(String name) { = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}7.新建一个springboot.jaxrs.webservice包并新建UsersService类package springboot.jaxrs.webservice;import java.util.HashMap;import java.util.Map;import javax.inject.Singleton;import javax.ws.rs.Consumes;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 javax.ws.rs.Produces;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.Response;import javax.ws.rs.core.Response.Status;import com.fasterxml.jackson.core.JsonProcessingException;import com.fasterxml.jackson.databind.ObjectMapper;import er;@Path("/ws/users")@Singleton//设置为单例,要不然userMap每次都会new一个新的public class UsersService {Map<String,User> userMap = new HashMap<>();@GET@Path("/getAllUser")@Produces(value=MediaType.APPLICATION_JSON) //JSON方式返回public Response getAllUser() {try {String userJson = new ObjectMapper().writeValueAsString(userMap);return Response.status(Status.OK).entity(userJson).build();} catch (JsonProcessingException e) {// TODO Auto-generated catch blocke.printStackTrace();returnResponse.status(Status.OK).entity("{\"error\":\""+e.toString()+"\"}").build();}}@GET@Path("/{userid}/get")@Consumes(value=MediaType.APPLICATION_JSON) //JSON方式接受请求@Produces(value=MediaType.APPLICATION_JSON) //JSON方式返回public Response getById(@PathParam("userid") String userid) {try {String userJson = newObjectMapper().writeValueAsString(userMap.get(userid));return Response.status(Status.OK).entity(userJson).build();} catch (JsonProcessingException e) {// TODO Auto-generated catch blocke.printStackTrace();returnResponse.status(Status.OK).entity("{\"error\":\""+e.toString()+"\"}").build();}}@POST@Path("/{userid}/update")public Response update(@PathParam("userid") String userid, User user) { if(user.getName()!=null)userMap.get(userid).setName(user.getName());//if(user.getIdNo()!=null)//userMap.get(userid).setIdNo(user.getIdNo());if(user.getPassword()!=null)userMap.get(userid).setPassword(user.getPassword());String output = userid + " 属性修改成功!";return Response.status(Status.OK).entity(output).build();}@PUT@Path("/{userid}/addOrReplace")@Consumes(value=MediaType.APPLICATION_JSON) //JSON方式接受请求@Produces(value=MediaType.TEXT_PLAIN) //纯文本方式返回public Response addOrReplace(@PathParam("userid") String userid, User user) { try {userMap.put(userid,user);return Response.status(Status.OK).entity("增添用户成功,用户信息:"+user.toString()).build();}catch(Exception e) {return Response.status(Status.OK).entity("增添用户失败,错误信息:"+e.toString()).build();}}@DELETE@Path("/{userid}/delete")public Response delete(@PathParam("userid") String userid) {userMap.remove(userid);String output = userid + " 删除成功!";return Response.status(Status.OK).entity(output).build();}}8.在src/main/resources建立一个application.properties文件server.servlet.context-path=/RestWS9.至此,工程已经搭建完毕,可以直接运行SpringBootRun的main方法启动程序10.也可以把pom.xml文件的打包类型改为<packaging>war</packaging>用外置Tomcat运行(必须要Tomcat 8.5或以上版本)二.使用Java编写客户端进行访问测试(使用Junit5进行单元测试)11.在src/test/java新建一个junittest包并新建UserTest类,然后直接执行:右键->Run As->Junit Test即可,无需手动启动SpringBootRun服务package junittest;import .URI;import javax.ws.rs.client.ClientBuilder;import javax.ws.rs.client.Entity;import javax.ws.rs.client.WebTarget;import javax.ws.rs.core.MediaType;import javax.ws.rs.core.Response;import org.junit.jupiter.api.BeforeEach;import org.junit.jupiter.api.Test;import org.junit.jupiter.api.MethodOrderer;import org.junit.jupiter.api.Order;import org.junit.jupiter.api.TestMethodOrder;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.context.annotation.Description;import springboot.jaxrs.SpringBootRun;import er;@TestMethodOrder(MethodOrderer.OrderAnnotation.class)//搭配@Order可以实现按顺序执行,但是@Test一定要使用JUnit5的注解才起作用@SpringBootTest(classes = SpringBootRun.class, webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)//指定了程序入口SpringBootRun和使用默认端口,执行JUnit Test的时候会自动启动项目,无需手动启动项目public class UserTest {private URI uri;private User user;@BeforeEachpublic void init() throws Exception {uri = new URI("http://127.0.0.1:8080/RestWS/services/ws/users");user = new User("xiaohong","ID0001","123456");}@Test@Order(1)@Description("添加或替换用户")public void addOrUpdateTest() {System.out.println("==================================1==================== ================");WebTarget target =ClientBuilder.newClient().target(uri).path("/"+user.getIdNo()+"/addOrReplace");Response res =target.request().accept(MediaType.TEXT_PLAIN).put(Entity.entity(user, MediaType.APPLICATION_JSON));System.out.println("状态码:"+res.getStatus());if (res.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+res.getStatus());}String output = res.readEntity(String.class);System.out.println(output);System.out.println("======================================================= ===============");}@Test@Order(2)@Description("获取单个用户")public void getByIdTest() {System.out.println("==================================2==================== ================");WebTarget target =ClientBuilder.newClient().target(uri).path("/"+user.getIdNo()+"/get");Response res =target.request().accept(MediaType.APPLICATION_JSON).get();System.out.println("状态码:"+res.getStatus());if (res.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+res.getStatus());}String output = res.readEntity(String.class);System.out.println(output);System.out.println("======================================================= ===============");}@Test@Order(3)@Description("修改用户")public void updateTest() {System.out.println("==================================3==================== ================");user.setName("小红");WebTarget target =ClientBuilder.newClient().target(uri).path("/"+user.getIdNo()+"/update");Response res =target.request().accept(MediaType.TEXT_PLAIN).post(Entity.entity(user, MediaType.APPLICATION_JSON));System.out.println("状态码:"+res.getStatus());if (res.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+res.getStatus());}String output = res.readEntity(String.class);System.out.println(output);System.out.println("======================================================= ===============");}@Test@Order(4)@Description("获取全部用户")public void getAllUserTest() {System.out.println("==================================4==================== ================");WebTarget target =ClientBuilder.newClient().target(uri).path("/getAllUser");Response res =target.request().accept(MediaType.APPLICATION_JSON).get();System.out.println("状态码:"+res.getStatus());if (res.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+res.getStatus());}String output = res.readEntity(String.class);System.out.println(output);System.out.println("======================================================= ===============");}@Test@Order(5)@Description("删除用户")public void deleteTest() {System.out.println("==================================5==================== ================");WebTarget target =ClientBuilder.newClient().target(uri).path("/"+user.getIdNo()+"/delete");Response res =target.request().accept(MediaType.APPLICATION_JSON).delete();System.out.println("状态码:"+res.getStatus());if (res.getStatus() != 200) {throw new RuntimeException("Failed : HTTP error code : "+res.getStatus());}String output = res.readEntity(String.class);System.out.println(output);System.out.println("======================================================= ===============");}}三.使用html页面访问Restful服务12.在src/main/resources里新建static文件夹,再在static文件夹新建js,pages 2个文件夹,然后js文件夹引入axios.min.js,vue.min.js。

JAXRS 1.0规范

JAXRS 1.0规范

JSR311 JAX-RS 1.0规范目录1. 概览 (4)2. Applications (4)2.1. 配置 (4)2.2. 发布 (4)3. 资源(Resources) (4)3.1. 资源类 (5)3.1.1. 生命周期和环境 (5)3.1.2. 构造函数 (5)3.2. 字段和属性 (5)3.3. 方法 (6)3.3.1. 可见性 (6)3.3.2. 参数 (7)3.3.3. 返回类型 (7)3.3.4. 异常 (8)3.3.5. HEAD和OPTIONS请求 (8)3.4. URI 模板(URI Templates) (9)3.4.1. 子资源 (9)3.5. 声明所支持的媒体类型(Declaring Media Type Capabilities) (10)3.6. 注释继承 (11)3.7. 请求与资源方法之间的映射 (11)3.7.1. 请求预处理 (12)3.7.2. 请求匹配 (12)3.7.3. 将URI模板转换成规则表达式 (15)3.8. 决定响应的媒体类型 (16)4. 提供者(Providers) (18)4.1.生命周期与环境 (18)4.1.1. 构造函数 (18)4.2.实体提供者(Entity Providers) (18)4.2.1.Message Body Reader (18)4.2.2. Message Body Writer (19)4.2.3.声明所支持的媒体类型 (19)4.2.4.标准实体提供者 (20)4.2.5.编码转换 (20)4.2.6.内容编码 (20)4.3.上下文提供者(Context Providers) (20)4.3.1.声明所支持的媒体类型 (21)4.4.异常映射提供者(Exception Mapping Providers) (21)5.上下文(Context) (21)5.1.并发 (21)5.2.上下文类型 (21)5.2.1.URIs和URI模板 (21)5.2.2.Headers (22)5.2.3. 内容协商和前置条件 (22)5.2.4.安全上下文 (24)5.2.5.Providers (25)6.环境 (25)6.1.Servlet容器 (25)6.2.Java EE容器 (25)6.3.其它 (25)7.运行时委托(Runtime Delegate) (25)7.1.配置 (26)附录A:注释汇总 (27)附录B:HTTP Header支持 (28)1. 概览2. ApplicationsJSR-311应用程序由一个或多个Resource,以及零个或多个Provider构成。

Java RESTful Web Service实战(第2版

Java RESTful Web Service实战(第2版

读书笔记
粗略看完,覆盖面广,最大的感受是java web写起来非常笨重,人生苦短。
深刻解读JAX-RS的标准和API设计;Jersey的使用要点和实现原理,以及基于REST的Web服务的设计思想和 原则自第1版发行后,Jersey的版本由2.9更新到了2.22.2,此间REST服务得到了更广泛的认可和使用。
搞技术的人,是停不下来的。时而要开疆拓土,学习和研究新的知识点,弥补自己的技术债;时而要运筹帷 幄,将知识点梳理成线,编织成;时而要深耕细作,面对当下要攻坚的业务所对应的知识点,深入研究、反复实 践、勤于思考、勇于交流。
安全性是指外系统对该接口的访问,不会使服务器端资源的状态发生改变;幂等性(idempotence)是指外 系统对同一REST接口的多次访问,得到的资源状态是相同的。
10.1身份认证 10.2资源授权
10.3认证与授权实 现
10.4 JAX-RS2实现
10.5 REST服 务与OAuth2
10.6本章小结
10.1.1基本认证 10.1.2摘要认证 10.1.3表单认证 10.1.4证书认证
10.2.1容器管理权限 10.2.2应用管理权限
10.3.1基本认证与JDBCRealm 10.3.2摘要认证与UserDatabaseRealm 10.3.3表单认证与DataSourceRealm 10.3.4 Form认证和JAASRealm 10.3.5证书认证与UserDatabaseRealm
1.2.1 REST式的Web服务 1.2.2对比RPC风格 1.2.3对比MVC风格
1.3.1 JAX-RS2标准 1.3.2 JAX-RS2的目标 1.3.3非JAX-RS2的目标 1.3.4解读JAX-RS元素

jaxrscxf的实现与集成

jaxrscxf的实现与集成

jaxrscxf的实现与集成依赖本文基于cxf2.7.0,需要在前面的例子中加入对jaxrs的依赖:Xml代码&lt;dependency&gt;&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;&lt;artifactId&gt;cxf-rt-frontend-jaxrs&lt;/artifactId&gt;&lt;version&gt;2.7.0&lt;/version&gt; &lt;/dependency&gt; 由于2.7.0是采用jax-rs2.0版本,即JSR339,默认会引入:Java代码&lt;dependency&gt;&lt;groupId&gt;javax.ws.rs&lt;/groupId&gt;&lt;artifactId&gt;javax.ws.rs-api&lt;/artifactId&gt;&lt;version&gt;2.0-m10&lt;/version&gt;&lt;/dependency&gt;当然对于之前的版本,基于jsr311。

需要在pom中手动加入:1.0或1.1版本Java代码&lt;dependency&gt;&lt;groupId&gt;javax.ws.rs&lt;/groupId&gt;&lt;artifactId&gt;jsr311-api&lt;/artifactId&gt;&lt;version&gt;1.1.1&lt;/version&gt;&lt;/dependency&gt;整合这里主要考虑一下几种整合方式,更多见这里编程式发布server在CXF中与JAX-WS一样,提供了JAXRSServerFactoryBean 作为工厂服务类来编程式发布资源类Java代码JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean(); //Bind one or more resources sf.setResourceClasses(CustomerService.class, AnotherService.class); // JAX-RS默认是每个请求会实例,这样修改为单例sf.setResourceProvider(CustomerService.class, new SingletonResourceProvider(new CustomerService()));sf.setAddress("http://localhost:9000/"); BindingFactoryManager manager =sf.getBus().getExtension(BindingFactoryManager.class); JAXRSBindingFactory factory = new JAXRSBindingFactory(); factory.setBus(sf.getBus());manager.registerBindingFactory(JAXRSBindingFactory.JAXRS _BINDING_ID, factory); sf.create();spring当然这里说的与spring整合少不了与web容器的整合,首先需要在web.xml中添加CXF的servlet监听请求路径:Xml代码&lt;servlet&gt;&lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;&lt;servlet-class&gt;org.apache.cxf.transport.servlet.CXFServle t&lt;/servlet-class&gt;&lt;load-on-startup&gt;5&lt;/load-on-startup&gt;&lt;/servlet&gt; &lt;servlet-mapping&gt;&lt;servlet-name&gt;CXFServlet&lt;/servlet-name&gt;&lt;url-pattern&gt;/*&lt;/url-pattern&gt;&lt;/servlet-mapping&gt;下面介绍两种spring的配置,这也是通用的jaxrs命名空间这是一个最简单的配置:Xml代码&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;beansxmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance" xmlns:jaxrs="/jaxrs"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xs d /jaxrs/schemas/jaxrs.xsd"&gt;&lt;import resource="classpath:META-INF/cxf/cxf.xml" /&gt; &lt;import resource="classpath:META-INF/cxf/cxf-servlet.xml" /&gt; &lt;jaxrs:server id="customerService" address="/jaxrs"&gt; &lt;jaxrs:serviceBeans&gt; &lt;ref bean="restPathService1"/&gt;&lt;/jaxrs:serviceBeans&gt; &lt;/jaxrs:server&gt; &lt;bean id="restPathService1"class="org.ws.server.cxf.chap3.cxf.server.CustomerService"/&gt; &lt;/beans&gt;当然在jaxrs:server中可以加入其他节点,具体可参考/schemas/jaxrs.xsdspring bean也可以使用普通的bean配置,只是需要作为JAXRSServerFactoryBean实例的属性:Xml代码&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;beansxmlns="/schema/beans" xmlns:xsi="/2001/XMLSchema-instance" xsi:schemaLocation="/schema/beans/schema/beans/spring-beans.xs d"&gt; &lt;importresource="classpath:META-INF/cxf/cxf.xml" /&gt;&lt;import resource="classpath:META-INF/cxf/cxf-servlet.xml" /&gt; &lt;beanclass="org.apache.cxf.jaxrs.JAXRSServerFactoryBean"init-method="create"&gt; &lt;propertyname="address" value="/jaxrs"/&gt;&lt;property:serviceBeans&gt; &lt;ref bean="restPathService1" /&gt;&lt;/property:serviceBeans&gt; &lt;/bean&gt;&lt;bean id="restPathService2"class="org.ws.server.cxf.chap3.cxf.server.AnotherService"/&gt; &lt;/beans&gt;数据绑定(Data Bindings)CXF对JAX-RS的数据绑定与之前的一样,需要选择相应的绑定类型,如需要加入JAXB对XML的处理:Xml代码&lt;dependency&gt;&lt;groupId&gt;org.apache.cxf&lt;/groupId&gt;&lt;artifactId&gt;cxf-rt-databinding-jaxb&lt;/artifactId&gt;&lt;version&gt;${cxf.version}&lt;/version&gt;&lt;/dependency&gt;这也是CXF对JAX-RS的默认编码类型,因此我们在采用XML作为传输时只需要做简单的处理:资源类中的一个方法:Java代码@GET @Path("/meth1")@Produces({ MediaType.APPLICATION_XML }) public User meth1() { return new User(1, "robin", "123"); }其中User作为返回需要以XML的格式传输,最简单的处理只需要在:Java代码@XmlRootElement(name = "user") public class User { private Integer id; private String username; private String password;当然更多操作需要了解再介绍对JSON格式的处理,由于CXF默认支持是依赖Jettison通常我们更喜欢Jackson。

基于JAX-RS规范的webService入门

基于JAX-RS规范的webService入门

基于JAX-RS规范的webService⼊门1、WebService概述1.1、什么是WebService?WebService(WEB服务)能够快捷和⽅便地综合结合各种系统、商务和任何应⽤平台。

利⽤最新的WebService标准能够使任何软件系统和系统之间的应⽤互通互联,⽅便⽽且廉价。

2、WebService的三个规范:Java中共有三种WebService规范,分别是Jax-WS(操作过于繁琐)、Jax-RS、JAXM&SAAJ(废弃)3、Apache的CXFApache CXF = Celtix + Xfire,开始叫Apache CeltiXfire,后来改名为Apache CXF了,以下简称CXF。

Apache CXF是⼀个开源的web service 框架,CXF帮助您构建和开发web service,它⽀持多种协议,如SOAP1.1,2 XML/HTTP、RESTful或者CORBA。

RESTful:⼀种风格⽽不是⼀个协议。

它理念上是⽹络上的所有事务都被抽象化为资源,每个资源对应⼀个唯⼀的资源标识符。

灵活部署:可以运⾏在Tomcat,Jboss,Jetty(内置),webLogic上⾯。

4、基于JAX-RS规范的⼊门4.1、JAX-RS介绍JAX-RS是⼀个是Java编程语⾔接⼝,被设计⽤来简化使⽤REST架构的应⽤程序开发JAX=RS API使⽤Java编程语⾔的注解来简化RESTful web Service的开发。

开发⼈员使⽤JAX-RS的注解修饰Java编程语⾔的类⽂件来定义资源和能够应⽤在资源上的⾏为。

JAX-RS的注解是运⾏时的注解,因此运⾏的映射会为资源⽣成辅助类和其他的辅助⽂件。

包含JAX-RS资源类的Java EE应⽤程序中资源时被配置好的。

辅助类和辅助⽂件是⽣成的,资源通过被发布到Java EE 服务器上来公开给客户端。

下表列出了JAX-RS定义的⼀些Java注解以及怎样使⽤他们的简要的描述。

JAX-RS 2.0:REST 式 Web 服务 API 中新增的和值得关注的功能

JAX-RS 2.0:REST 式 Web 服务 API 中新增的和值得关注的功能
5版权所有© 2012,Oracle 和/或其关联公司。保留所有权利。
JAX-RS 注解(续)
注解
@PathParam @QueryParam @CookieParam @HeaderParam @FormParam @MatrixParam
目的
绑定来自 URI 的值,例如 @PathParam(“id”) 绑定查询名称的值/查询值,例如 @QueryParam(“name”) 绑定 cookie 的值,例如 @CookieParam(“JSESSIONID”) 绑定 HTTP 标头的值,例如 @HeaderParam(“Accept”) 绑定 HTML 表单的值,例如 @FormParam(“name”) 绑定矩阵参数的值,例如 @MatrixParam(“name”)
7版权所有© 2012,Oracle 和/或其关联公司。保留所有权利。
JAX RS 2.0 客户端 API
8版权所有© 2012,Oracle 和/或其分支机构。保留所有权利。
插入幻灯片 13 中的保护政策分类等级
客户端 API
动机
HTTP 客户端库太低级 利用 JAX-RS 1.x API 中的提供商/概念
19版权所有© 2012,Oracle 和/或其关联公司。保留所有权利。
通用配置
public interface Configurable { Configuration getConfiguration(); Configurable property(String name, Object value); Configurable register(...); } public interface Configuration { Set<Class> getClasses(); Map<Class,Integer> getContracts(Class componentClass); Set<Object> getInstances(); Map<String,Object> getProperties(); Object getProperty(String name); Collection<String> getPropertyNames(); boolean isEnabled(Feature feature); boolean isRegistered(Object component); ...
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

资源类和资源方法的注解
@javax.ws.rs.Path 标注资源类的URI,该注解也可以用于类中的资源方法。 @javax.ws.rs.GET 标注该资源类中处理HTTP协议中GET请求的资源方法,经 常用于查询。该资源方法应做到幂等。 @javax.ws.rs.POST 标注该资源类中处理HTTP协议中POST请求的资源方法, 通常用于资源的创建,资源标识由服务器端产生。 @javax.ws.rs.PUT 标注该资源类中处理HTTP协议中PUT请求的资源方法,经 常用于更新,有时也用于资源的创建,但创建资源所需的标 识应由客户端提供。该资源方法应做到幂等。
单例模式的Application示例
/* 该示例实现了getClasses抽象方法的同时,改写了 getSingletons方法,将Hello资源类设置为单例模式。 ---------------------------------------------------------------------------------*/ @javax.ws.rs.ApplicationPath("/singletonres") public class ApplicationConfig extends Application{ Set<Object> singletons= new java.util.HashSet(); public Set<Class<?>> getClasses(){ return Collections.emptySet(); } @Override public Set<Object> getSingletons() { return singletons.add(new Hello()); } }
路径模板和@PathParam注解
用@Path定义资源的URI时,可以利用"{模板名}"定义路径模 板,匹配任意字符形成的路径信息。模板名的实际值可通过 @PathParam注入给资源方法的对应参数。 @Path("/hello") @Path定义了参数name,该参数名 称可以传递给@PathParam注解 public class Hello{ @GET @Path("{name}") public String sayHello(@PathParam("name") String name){ return "hello,"+name; } }
请求实例模式的Application示例
/* ApplicationConfig继承Application类,实现了getClasses抽象 方法,将Hello资源类设置为请求实例化方式。 另外,可以使用类级注解ApplicationPath设置该Web程序中 Web服务资源的URL模式,此示例中设置为/resource。 ---------------------------------------------------------------------------------*/ @javax.ws.rs.ApplicationPath("/resource") public class ApplicationConfig extends Application{ Set<Class<?>> prototypes= new java.util.HashSet(); @Override public Set<Class<?>> getClasses(){ prototypes.add(Hello.class); return prototypes; } }
}
getClasses和getSingletons方法
public abstract Set<Class<?>> getClasses() 此方法返回java.util.Set类型的一个集合,该集合中存储的是 以请求实例化模式的资源类的Class对象,Class对象的获取 可以通过表达式"类名.class"获取。 public Set<Object> getSingletons() 此方法返回的是以需要以单例模式建立实例的资源类的具体 实例的java.util.Set类型的集合。在该方法中,可以直接建立 对应资源类的实例,然后将这些实例加入到Set集合中,返回 该Set集合即可。
//GET标注的资源方法必须也是公开的,处理GET请求 @GET public String sayHello(){ return "hello,world!"; } }
资源类的实例化
如前所述,JAX-RS服务是Web程序的一部分,当用户请求到来 的时候,容器将建立资源类的实例,建立的方式有两种: 请求实例 这种方式是每接到用户请求,都将建立对应的资源类的实例。 单例模式 所有请求都使用同一个资源类的实例
Jersey服务的web.xml配置示例
<servlet> <servlet-name>ServletAdaptor</servlet-name> <servlet-class> org.glassfish.jersey.servlet.ServletContainer </servlet-class> <init-param> <param-name>javax.ws.rs.Application</param-name> <param-value>rs.ApplicationConfig</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>ServletAdaptor</servlet-name> <url-pattern>/resource/*</url-pattern> </servlet-mapping>
基于JAX-RS的RESTful Web 服务的构建
REST风格Web服务的构建框架
建立基于REST风格的Web服务可以采用一些技术框架简化构 建过程,常用的技术框架包括: WCF 微软提供的基于.NET技术的RESTful Web服务构架的框架 ,可以使用.NET支持的各种语言编写服务实现代码。 JAX-RS规范 由Java标准化组织JCP()制定的构建 RESTful风格的Web服务的技术规范,目前最新的规范版本是 2.1(JSR370)。 SpringFramework 是Spring的生态圈中对REST风格Web服务的实现。
在web.xml中设置资源类
使用@ApplicationPath设置服务资源的URL模式适用于直接 支持JAX-RS规范的容器或者实现了Servlet3.0及以上的规范 Servlet/JSP容器(如Tomcat7.x及以上版本)中部署时可用。 对于仅支持Servlet2.5规范的容器(如Tomcat6.x),JAX-RS 的实现类库一般会提供在web.xml中利用类似Servlet的配置 方式配置服务资源的URL模式。 例如,org.glassfish.jersey.servlet.ServletContainer是Jersey 提供的配置Servlet,它有一个名为"javax.ws.rs.Application" 的起始参数,用于设定Web服务中继承Application的子类类 名,配置该Servlet的url-pattern,就可设置Web程序中的 JAX-RS服务的URL模式。
资源类和资源方法的注解
@javax.ws.rs.DELETE 标注该资源类中处理HTTP协议中DELETE请求的资源方法 ,通常用于资源删除。该资源方法应做到幂等。 @javax.ws.rs.HEAD 标注该资源类中处理HTTP协议中HEAD请求的资源方法, 通常用于资源中元数据的获取。 @javax.ws.rs.OPTIONS 标注该资源类型中处理HTTP协议中OPTIONS请求的资源 方法,通常用于查询可用于资源的操作。
JAX-RS服务的部署
利用JAX-RS规范开发的Web服务是Java Web程序 (WAR文件)的一部分,可以直接部署在支持JavaEE6 或者JavaEE7全部功能的服务器中(例如GlassFish3.x或 者4.x版本),也可以部署在仅支持Servlet/JSP及规范的 服务器中(例如Tomcat)。 当在Servlet/JSP容器中部署时,需要在Web程序中添加 对应的JAX-RS实现类库(例如Jersey)。如果需要使用 JAX-RS的服务端事件(SSE),则要求容器必须支持 Servlet3.0规范(例如,Tomcat7.x及以上版本);否则只 要求容器支持Servlet2.5规范即可(例如,Tomcat6.x版 本)。
资源类示例
import javax.ws.rs.PATH; import javax.ws.rs.GET; //PATH注解使用String类型的value参数,设定资源类的URI @Path("/hello") //value参数名可以省略 public class Hello{//资源类必须是公开的
@QueryParam示例
@Path("/cal") public class CalReSource{ @GET public int add(@QueryParam("n") int n, @QueryParam("m") int m){ return n+m; } }
资源类和资源方法
如前所述,ROA中的资源就是可以用URI描述的信息,在 JAX-RS中,资源就是部署在Web程序中,可通过URI请求到 的资源类实例。 资源类 使用@javax.ws.rs.Path注解定义其URI的公开类,JAX-RS 也允许使用接口(interface)的实例作为资源。 资源方法 资源类或接口中能够处理诸如GET、POST等不同请求方式 的公开方法。
相关文档
最新文档