Restful Web Services(JAX-RS)
Restful的WebService说明
之前的章节都是基于SOAP的,接下来介绍基于Restful风格的WebService。
Rest风格介绍
常见状态码
503网站不存在,服务无效,可以试试访问被墙掉的网站。
JAX-RS
JAX-RS = Java Architecture For Restful Web Services(JSR311)
JAX-RS是JavaEE6引入的一个新规范。是一个Java编程语言的应用程序接口,支持按照表述性状态转移(REST)架构风格创建WEB服务。
JAX-RS使用了Java SE5引入的Java注解来简化Web服务的客户端和服务端开发和部署。
JAX-RS提供了一些注解标注资源类和POJO,封装为Web资源,如下:
基于JAX-RS实现的框架有Jersey,RESTEasy等。
这两个框架创建的应用可以很方便地部署到Servlet容器中。
示例程序
-
新建springboot工程,引入相关jar包
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
<?xml version="1.0" encoding="UTF-8"?> <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/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> <relativePath/> </parent> <groupId>org.eh</groupId> <artifactId>springboot-cxf</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- CXF webservice --> <dependency> <groupId>org.apache.cxf</groupId> <artifactId>cxf-spring-boot-starter-jaxrs</artifactId> <version>3.3.4</version> </dependency> <!--lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> </dependency> </dependencies> </project>
-
建Book.java的entity并添加注解@XmlRootElement
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
package com.eh.cxf; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement @Data @AllArgsConstructor @NoArgsConstructor public class Book { private long id; private String bookName; private double price; }
-
建HelloService接口并添加Restful风格相关的注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14
package com.eh.cxf; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @Path("/book") public interface HelloService { @GET @Path("/{id}") @Produces(MediaType.APPLICATION_XML) // 表示输出为xml @Consumes(MediaType.WILDCARD) // 表示输入为 */* Book sayHello(@PathParam("id") Integer id); }
-
编写HelloServiceImpl实现类
1 2 3 4 5 6 7 8 9 10 11 12 13 14
package com.eh.cxf; import org.springframework.stereotype.Service; @Service public class HelloServiceImpl implements HelloService { @Override public Book sayHello(Integer id) { System.out.println("@PathParam get id:" + id); Book book = new Book(100L, "水浒传", 25.5); return book; } }
-
yml,配置cxf路径和包扫描
1 2 3 4 5 6 7 8 9
server: port: 9999 cxf: path: /hello servlet.init: service-list-path: /info jaxrs: # 配置扫描服务,必须要设置为true,否则找不到要暴露的服务 component-scan: true
-
启动主程序
启动后注意目前用rest而不是soap,所以没有WSDL的描述了。
1 2 3 4 5 6 7 8 9 10 11
package com.eh; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootCxfApplication { public static void main(String[] args) { SpringApplication.run(SpringBootCxfApplication.class, args); } }
-
浏览器地址栏里面按照Restful风格的路径进行访问和测试
http://localhost:9999/hello/book/1
服务端返回json
-
此时实体类不需要再加注解@XmlRootElement
-
引入jaxrs转json工具
1 2 3 4 5 6
<!--jaxrs转json工具--> <dependency> <groupId>com.fasterxml.jackson.jaxrs</groupId> <artifactId>jackson-jaxrs-json-provider</artifactId> <version>2.8.5</version> </dependency>
-
jaxb默认支持xml格式, 而实现对象转json是需要额外的转换器的,往容器中注入MessageBodyReader,这里使用实现类JacksonJaxbJsonProvider,这样cxf在将对象转为json时会自动使用这个工具对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
package com.eh; import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class SpringBootCxfApplication { public static void main(String[] args) { SpringApplication.run(SpringBootCxfApplication.class, args); } // 配置一个对象与json转换的工具 @Bean public JacksonJaxbJsonProvider jacksonJaxbJsonProvider() { return new JacksonJaxbJsonProvider(); } }
-
接口上添加输出类型为
application/json
的注解1 2 3 4 5 6 7 8 9 10 11 12 13 14
package com.eh.cxf; import javax.ws.rs.*; import javax.ws.rs.core.MediaType; @Path("/book") public interface HelloService { @GET @Path("/{id}") @Produces(MediaType.APPLICATION_JSON) // 表示输出为json @Consumes(MediaType.WILDCARD) // 表示输入为 */* Book sayHello(@PathParam("id") Integer id); }
-
验证
使用HttpClient进行访问
HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。
使用步骤
-
引入httpclient jar包
1 2 3 4 5 6
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.12</version> </dependency>
-
使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
package com.eh.cxf; import lombok.SneakyThrows; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; public class ClientTest { @SneakyThrows public static void main(String[] args) { // 创建HttpClient实例 HttpClient httpClient = HttpClients.custom().build(); // 调用 HttpResponse httpResponse = httpClient.execute(new HttpGet("http://localhost:9999/hello/book/1")); // 将InputStream转换成String输出 System.out.println(EntityUtils.toString(httpResponse.getEntity())); } }