Java RESTful Web Service实战(第2版) 2.5 处理响应

2.5 处理响应

REST的响应处理结果应包括响应头中HTTP状态码,响应实体中媒体参数类型和返回值类型,以及异常情况处理。JAX-RS2支持4种返回值类型的响应,分别是无返回值、返回Response类实例、返回GenericEntity类实例和返回自定义类实例。如下,逐一讲述这4种返回值类型。

阅读指南

本节示例源代码地址:https://github.com/feuyeux/jax-rs2-guide-II/tree/master/2.simple-service-3。

相关包:com.example.response。

2.5.1 返回类型

1. void

在返回值类型是void的响应中,其响应实体为空,HTTP状态码为204。在前面的DELETE方法讲述中已经介绍过,再来看一下这种类型的资源方法。

@DELETE

@Path("{s}")

//关注点1:无返回值的DELETE方法

public void
delete(@PathParam("s") final String s) {

   
LOGGER.debug(s);

}

因为delete操作无须返回更多的关于资源表述的信息,因此该方法没有返回值,即返回值类型为void,见关注点1。

2. Response

在返回值类型为Response的响应中,响应实体为Response类的entity()方法定义的实体类实例。如果该内容为空,则HTTP状态码为204,否则HTTP状态码为200 OK,示例代码如下。

@POST

@Path("c")

public Response get(final String s) {

   
LOGGER.debug(s);

   
//Response.noContent().build();

//关注点1:构建无返回值的响应实例

   
return Response.ok().entity("char[]:" + s).build();

}

在这段代码中,Response首先定义了HTTP的状态码为ok,然后填充实体信息,最后调用build()方法构建Response实例,见关注点1。

3. GenericEntity

通用实体类型作为返回值的情况并不常用。其形式是构造一个统一的实体实例并将其返回,实体实例作为第一个参数、该实体类型作为第二个参数,示例代码如下。

@POST

@Path("b")

public String get(final byte[] bs) {

   
for (final byte b : bs) {

       
LOGGER.debug(b);

    }

   
return "byte[]:" + new String(bs);

}

/*

public GenericEntity<String>
get(final byte[] bs) {

   
for (final byte b : bs) {

       
LOGGER.debug(b);

    }

  //关注点1:构建GenericEntity实例

   
return new GenericEntity<String>("byte[]:" + new
String(bs), String.class);

}

*/

在这段代码中,GenericEntity的第一个是由byte数组实例作为参数构建的字符串实例,第二个参数是字符串类,见关注点1。

4. 自定义类型

JDK中的类(比如File、String等)都可以作为返回值类型,更常用的是返回自定义的POJO类型,前述多个例子就是这样做的,再来看一个示例。

@POST

@Path("f")

//关注点1:GET方法的返回类型为File

public File get(final File f) throws
FileNotFoundException, IOException {

   
try (BufferedReader br = new BufferedReader(new FileReader(f))) {

       
String s;

       
do {

           
s = br.readLine();

           
LOGGER.debug(s);

        } while (s != null);

       
return f;

    }

}

@POST

@Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})

@Produces(MediaType.APPLICATION_XML)

//关注点2:POST方法的返回值是自定义类Book

public Book getEntity(Book book) {

   
LOGGER.debug(book.getBookName());

   
return book;

}

@POST

@Consumes({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON})

@Produces(MediaType.APPLICATION_XML)

//关注点3:POST方法的返回值是自定义类Book

public Book
getEntity(JAXBElement<Book> bookElement) {

   
Book book = bookElement.getValue();

   
LOGGER.debug(book.getBookName());

   
return book;

}

在这段代码中,返回值类型有来自JDK的File类型,见关注点1,也有自定义的POJO类型,见关注点2和关注点3。

2.5.2 处理异常

实现REST的资源方法时应使其具有良好的异常处理能力,这包括异常的定义和错误状态码的正确返回。

1. 处理状态码

首先通过表2-7了解下REST中常用的HTTP状态码,应当在处理异常的同时,为REST请求的客户端提供对应的错误码。

表2-7 HTTP常用状态码列表

状态码     含  义

200 OK     服务器正常响应

201 Created     创建新实体,响应头Location指定访问该实体的URL

202 Accepted  服务器接受请求,处理尚未完成。可用于异步处理机制

204 No Content        服务器正常响应,但响应实体为空

301 Moved Permanently 请求资源的地址发生永久变动,响应头Location指定新的URL

302 Found         请求资源的地址发生临时变动

304 Not Modified     客户端缓存资源依然有效

400 Bad Request     请求信息出现语法错误

401 Unauthorized    请求资源无法授权给未验证用户

403 Forbidden 请求资源未授权当前用户

404 Not Found 请求资源不存在

405 Method Not Allowed         请求方法不匹配

406 Not Acceptable          请求资源的媒体类型不匹配

500 Internal Server Error         服务器内部错误,意外终止响应

501 Not Implemented     服务器不支持当前请求

 

JAX-RS2规定的REST式的Web服务的基本异常类型为运行时异常WebApplicationException类。该类包含3个主要的子类分别对应如下内容。

HTTP状态码为3xx的重定向类RedirectionException;

HTTP状态码为4xx的请求错误类ClientErrorException;

HTTP状态码为5xx的服务器错误类ServerErrorException。

它们各自的子类对照HTTP状态码再细分,比如常见的HTTP状态码404错误,对应的错误类为NotFoundException,如图2-4所示。

除了Jersey提供的标准异常类型,我们也可以根据业务需要自定义相关的业务异常类,示例如下。

//关注点1:定义WebApplicationException接口实现类

public class Jaxrs2GuideNotFoundException
extends WebApplicationException {

   
public Jaxrs2GuideNotFoundException() {

//关注点2:定义HTTP状态

       
super(javax.ws.rs.core.Response.Status.NOT_FOUND);

    }

   
public Jaxrs2GuideNotFoundException(String message) {

       
super(message);

    }

}

在这段代码中,Jaxrs2GuideNotFoundException类继承自JAX-RS2的WebApplication-Exception类,见关注点1。其默认构造子提供了HTTP状态码,其值为Response.Status.NOT_FOUND,见关注点2。

 

图2-4 Jersey定义的异常类型

2. ExceptionMapper

Jersey框架为我们提供了更为通用的异常处理方式。通过实现ExceptionMapper接口并使用@Provider注解将其定义为一个Provider,可以实现通用的异常的面向切面处理,而非针对某一个资源方法的异常处理,示例如下。

@Provider

public class EntityNotFoundMapper

implements
ExceptionMapper<Jaxrs2GuideNotFoundException>{

   
//关注点1:定义ExceptionMapper接口实现类

   
@Override

   
public Response toResponse(final Jaxrs2GuideNotFoundException ex) {

     
//关注点2:拦截并返回新的响应实例

     
return Response.status(404).entity(ex.getMessage()).type("text/plain").build();

    }

}

在这段代码中,EntityNotFoundMapper实现了ExceptionMapper接口,并提供了泛型类型为前述刚定义的Jaxrs2GuideNotFoundException类,见关注点1;当响应中发生了Jaxrs2GuideNotFoundException类型的异常,响应流程就会被拦截并补充HTTP状态码和异常消息,以文本作为媒体格式返回给客户端,见关注点2。

时间: 2024-09-15 16:19:03

Java RESTful Web Service实战(第2版) 2.5 处理响应的相关文章

Java RESTful Web Service实战(第2版)

Java核心技术系列 Java RESTful Web Service实战 (第2版) 韩陆 著 图书在版编目(CIP)数据 Java RESTful Web Service实战 / 韩陆著. -2版. -北京:机械工业出版社,2016.7 (Java核心技术系列) ISBN 978-7-111-54213-1 Ⅰ. J-   Ⅱ. 韩-   Ⅲ. JAVA语言-程序设计   Ⅳ. TP312 中国版本图书馆CIP数据核字(2016)第156331号 Java RESTful Web Servi

Java RESTful Web Service实战(第2版) 导读

Java核心技术系列 Java RESTful Web Service实战 (第2版) 韩陆 著   半年前初识韩陆的时候,我们就聊到他正在写的这本书,当得知我从2006年就参与了Apache CXF开发,他立即邀请我为他的新书写序,我也就欣然答应了. Apache CXF作为JAXWS以及JAX-RS规范的实现框架,已经成为很多Web服务开发者必选的开发框架.作为这一框架的开发维护者之一,我的日常工作经常需要熟悉这些JSR规范,并实现JSR所定义的API,解决最终用户的使用问题. 熟悉Java

Java RESTful Web Service实战(第2版) 2.3 传输格式

2.3 传输格式 本节要考虑的就是如何设计表述,即传输过程中数据采用什么样的数据格式.通常,REST接口会以XML和JSON作为主要的传输格式,这两种格式数据的处理是本节的重点.那么Jersey是否还支持其他的数据格式呢?答案是肯定的,让我们逐一掌握各种类型的实现. 2.3.1 基本类型 Java的基本类型又叫原生类型,包括4种整型(byte.short.int.long).2种浮点类型(float.double).Unicode编码的字符(char)和布尔类型(boolean). 阅读指南 本

Java RESTful Web Service实战(第2版) 1.2 解读REST服务

1.2 解读REST服务 RESTful对应的中文是REST式的,RESTful Web Service的准确翻译应该是REST式的Web服务,我们通常简称为REST服务.RESTful的应用或者Web服务是最常见的两种REST式的项目部署.存在的方式.本节将介绍REST服务并对比其与传统Web Services的不同. 1.2.1 REST式的Web服务 RESTful Web Service是一种遵守REST式风格的Web服务.REST服务是一种ROA(Resource-Oriented A

Java RESTful Web Service实战(第2版) 1.3 解读JAX-RS标准

1.3 解读JAX-RS标准 JAX-RS是Java领域的REST式的Web服务的标准规范,是使用Java完成REST服务的基本约定. 1.3.1 JAX-RS2标准 Java领域中的Web Service是指实现SOAP协议的JAX-WS.直到Java EE 6(发布于2008年9月)通过JCP(Java Community Process)组织定义的JSR311(http://www.jcp.org/en/jsr/detail?id=311),才将REST在Java领域标准化. JSR311

Java RESTful Web Service实战(第2版) 1.4 Jersey项目概要

1.4 Jersey项目概要 Jersey是JAX-RS标准的参考实现,是Java领域中最纯正的REST服务开发框架.本节将带读者走近Jersey的世界. Jersey项目是GlashFish项目的一个子项目,专门用来实现JAX-RS(JSR 311 & JSR 339)标准,并提供了扩展特性. 1.4.1 获得Jersey Jersey项目的地址是https://jersey.java.net.该网站同时提供了JAX-RS和JAX-RS2两个并行版本,分别是JAX-RS1.1(截至本书发稿,最

Java RESTful Web Service实战(第2版) 1.5 快速实现Java REST服务

1.5 快速实现Java REST服务 本节包含两个Jersey实战示例,目的是让读者具备快速创建REST服务的能力. 在开始实战之前,首先需要读者确认你的环境是否已经安装了Java和Maven.这里使用Maven命令,示例如下. mvn -v   Apache Maven 3.3.3 (7994120775791599e205a5524ec3e0dfe41d4a06; 2015-04-22T19:57:37+08:00) Maven home: /usr/local/Cellar/maven/

Java RESTful Web Service实战(第2版) 1.7 Java领域的其他REST实现

1.7 Java领域的其他REST实现 Java领域存在很多REST实现,我们以是否遵循JAX-RS标准,将它们分为两组.前者是JAX-RS标准参考实现之外的厂商实现,后者要么是因为出现较JAX-RS标准早,要么干脆跳出了JAX-RS标准的定义,以自身框架一致性为目标,实现了一套独有的对REST开发的支持.本节将概括性地介绍这些实现工具,以便读者有所对比和选择. 1.7.1 JAX-RS的其他实现 JAX-RS标准发布后,诸多厂商推出了自己的基于JAX-RS标准的实现.其中最有影响力的当属来自J

Java RESTful Web Service实战(第2版) 1.9 本章小结

1.9 本章小结 本章主要讲述了REST服务的概念和实战.先后解读了REST.REST服务.JAX-RS2标准中的重要概念,对JAX-RS2的参考实现项目Jersey进行了简单而全面的概述.随后讲述了如何快速创建REST应用和REST服务,介绍了基于JAX-RS2标准的其他项目和其他非JAX-RS2标准的.著名的Java项目. 通过阅读本章,读者可以清楚地掌握Java领域开发REST服务中的基本概念. 本章主要的知识点如下. REST是什么 一种架构风格. HTTP+URI+XML是REST的基

Java RESTful Web Service实战(第2版) 1.6 快速了解Java REST服务

1.6 快速了解Java REST服务 1.6.1 REST工程类型 在REST服务中,资源类是接收REST请求并完成响应的核心类,而资源类是由REST服务的"提供者"来调度的.这一概念类似其他框架中自定义的Servlet类,该类会将请求分派给指定的Controller/Action类来处理.本节将讲述REST中的这个提供者,即JAX-RS2中定义的Application以及Servlet. Application类在JAX-RS2(JSR339,详见参考资料)标准中定义为javax.