`
zzc1684
  • 浏览: 1222884 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

JAX-RS入门 八: HTTP响应

阅读更多

首先先看一下HTTP中定义的响应码及其意义:

 

响应码
含义
100
继续
101
分组交换协议
200
OK
201
被创建
202
被采纳
203
非授权信息
204
无内容
205
重置内容
206
部分内容
300
多选项
301
永久地传递
302
找到
303
参见其他
304
未改动
305
使用代理
307
暂时重定向
400
错误请求
401
未授权
402
要求付费
403
禁止
404
未找到
405
不允许的方法
406
不被采纳
407
要求代理授权
408
请求超时
409
冲突
410
过期的
411
要求的长度
412
前提不成立
413
请求实例太大
414
请求URL太大
415
不支持的媒体类型
416
无法满足的请求范围
417
失败的预期
500
内部错误
501
未被使用
502
网关错误
503
不可用的服务
504
网关超时
505
HTTP版本未被支持

 

一、成功

 

从 200 到 399 为成功码,表示请求处理成功。

 

如果方法返回值不为null,则返回码是 200;如果返回值为 null 或者为 void,则返回码为 204,表示无内容。

 

二、错误

 

从 400 到 599 表示处理错误。

 

例如 404表示网页未找着;如果请求的期望的返回交换类型不对,则返回 406,表示不可接爱;如果请求的方法未找着,则返回 405,表示方法不允许,这个返回结果对于HEAD和OPTIONS请求方法例外,对于HEAD会试图去查找能处理相同URI的GET方法;对于OPTION,会返回一些自动生成的信息。

 

三、复杂的响应

 

对于不能简单处理的返回信息,则可以返回javax.ws.rs.core.Response对象:

Java代码 复制代码 收藏代码
  1. public abstract class Response {   
  2.   
  3.     public abstract Object getEntity();   
  4.     public abstract int getStatus();   
  5.     public abstract MultivaluedMap<String, Object> getMetadata();   
  6.     ...   
  7.   
  8. }   

Response对象不能直接创建,需要通过javax.ws.rs.core.Response.ResponseBuilder来创建:

Java代码 复制代码 收藏代码
  1. public abstract class Response {   
  2.   
  3.     ...   
  4.     public static ResponseBuilder status(Status status) {...}   
  5.     public static ResponseBuilder status(int status) {...}   
  6.     public static ResponseBuilder ok() {...}   
  7.     public static ResponseBuilder ok(Object entity) {...}   
  8.     public static ResponseBuilder ok(Object entity, MediaType type) {...}   
  9.     public static ResponseBuilder ok(Object entity, String type) {...}   
  10.     public static ResponseBuilder ok(Object entity, Variant var) {...}   
  11.     public static ResponseBuilder serverError() {...}   
  12.     public static ResponseBuilder created(URI location) {...}   
  13.     public static ResponseBuilder noContent() {...}   
  14.     public static ResponseBuilder notModified() {...}   
  15.     public static ResponseBuilder notModified(EntityTag tag) {...}   
  16.     public static ResponseBuilder notModified(String tag) {...}   
  17.     public static ResponseBuilder seeOther(URI location) {...}   
  18.     public static ResponseBuilder temporaryRedirect(URI location) {...}   
  19.     public static ResponseBuilder notAcceptable(List<Variant> variants) {...}   
  20.     public static ResponseBuilder fromResponse(Response response) {...}   
  21.     ...   
  22.   
  23. }   

ResponseBuilder是一个用来创建单个Response实例的工厂类, 首先将要创建的response对象的状态存起来,最后当状态设置完成了,就使用builder去初始化Response:

 

Java代码 复制代码 收藏代码
  1. public static abstract class ResponseBuilder {   
  2.   
  3.     public abstract Response build();   
  4.   
  5.     public abstract ResponseBuilder clone();   
  6.     public abstract ResponseBuilder status(int status);   
  7.   
  8.     public ResponseBuilder status(Status status) {...}   
  9.   
  10.     public abstract ResponseBuilder entity(Object entity);   
  11.     public abstract ResponseBuilder type(MediaType type);   
  12.     public abstract ResponseBuilder type(String type);   
  13.     public abstract ResponseBuilder variant(Variant variant);   
  14.     public abstract ResponseBuilder variants(List<Variant> variants);   
  15.     public abstract ResponseBuilder language(String language);   
  16.     public abstract ResponseBuilder language(Locale language);   
  17.     public abstract ResponseBuilder location(URI location);   
  18.     public abstract ResponseBuilder contentLocation(URI location);   
  19.     public abstract ResponseBuilder tag(EntityTag tag);   
  20.     public abstract ResponseBuilder tag(String tag);   
  21.     public abstract ResponseBuilder lastModified(Date lastModified);   
  22.     public abstract ResponseBuilder cacheControl(CacheControl cacheControl);   
  23.     public abstract ResponseBuilder expires(Date expires);   
  24.     public abstract ResponseBuilder header(String name, Object value);   
  25.     public abstract ResponseBuilder cookie(NewCookie... cookies);   
  26. }   

例如:

 

 

Java代码 复制代码 收藏代码
  1. @Path("/textbook")   
  2. public class TextBookService {   
  3.   
  4.     @GET  
  5.     @Path("/restfuljava")   
  6.     @Produces("text/plain")   
  7.     public Response getBook() {   
  8.         String book = ...;   
  9.         ResponseBuilder builder = Response.ok(book);   
  10.         builder.language("fr").header("Some-Header""some value");   
  11.         return builder.build();   
  12.     }   
  13.   
  14. }   

四、Cookie

 

JAX-RS使用了一个简单的类去表示一个cookie值,它就是javax.ws.rs.core.NewCookie:

Java代码 复制代码 收藏代码
  1. public class NewCookie extends Cookie {   
  2.   
  3.     public static final int DEFAULT_MAX_AGE = −1;   
  4.     public NewCookie(String name, String value) {}   
  5.     public NewCookie(String name, String value, String path,   
  6.     String domain, String comment,   
  7.     int maxAge, boolean secure) {}   
  8.     public NewCookie(String name, String value, String path,   
  9.             String domain, int version, String comment,   
  10.     int maxAge, boolean secure) {}   
  11.     public NewCookie(Cookie cookie) {}   
  12.     public NewCookie(Cookie cookie, String comment,   
  13.     int maxAge, boolean secure) {}   
  14.     public static NewCookie valueOf(String value)   
  15.             throws IllegalArgumentException {}   
  16.     public String getComment() {}   
  17.     public int getMaxAge() {}   
  18.     public boolean isSecure() {}   
  19.     public Cookie toCookie() {}   
  20.   
  21. }  

要返回Cookie,只需要传入它到Response中:

 

Java代码 复制代码 收藏代码
  1. @GET  
  2. public Response get() {   
  3.     NewCookie cookie = new NewCookie("key", "value);   
  4.     ResponseBuilder builder = Response.ok("hello""text/plain");   
  5. return builder.cookies(cookie).build();   
  6. }   

五、状态类别

 

除了直接写数据外,JAX-RS定义了一个状态值的枚举类别:

 

 

Java代码 复制代码 收藏代码
  1. public enum Status {   
  2.     OK(200"OK"),   
  3.     CREATED(201"Created"),   
  4.     ACCEPTED(202"Accepted"),   
  5.     NO_CONTENT(204"No Content"),   
  6.     MOVED_PERMANENTLY(301"Moved Permanently"),   
  7.     SEE_OTHER(303"See Other"),   
  8.     NOT_MODIFIED(304"Not Modified"),   
  9.     TEMPORARY_REDIRECT(307"Temporary Redirect"),   
  10.     BAD_REQUEST(400"Bad Request"),   
  11.     UNAUTHORIZED(401"Unauthorized"),   
  12.     FORBIDDEN(403"Forbidden"),   
  13.     NOT_FOUND(404"Not Found"),   
  14.     NOT_ACCEPTABLE(406"Not Acceptable"),   
  15.     CONFLICT(409"Conflict"),   
  16.     GONE(410"Gone"),   
  17.     PRECONDITION_FAILED(412"Precondition Failed"),   
  18.     UNSUPPORTED_MEDIA_TYPE(415"Unsupported Media Type"),   
  19.     INTERNAL_SERVER_ERROR(500"Internal Server Error"),   
  20.     SERVICE_UNAVAILABLE(503"Service Unavailable");   
  21.   
  22.     public enum Family {   
  23.         INFORMATIONAL, SUCCESSFUL, REDIRECTION,   
  24.         CLIENT_ERROR, SERVER_ERROR, OTHER   
  25.     }   
  26.   
  27.     public Family getFamily()   
  28.     public int getStatusCode()   
  29.     public static Status fromStatusCode(final int statusCode)   
  30. }   

每个Status的值都关联的到一个特定HTTP的返回值族,这个族由Status.Family标识。例如 100范围的值被认识是信息性的;200范围的是成功;300范围的也是成功,但是被重定向的;400是client错误;500是服务器错误。

 

Response.status()和ResponseBuilder.status()都接受一个Status值,例如:

 

    

Java代码 复制代码 收藏代码
  1. @DELETE  
  2. Response delete() {   
  3.   
  4.     ...   
  5.     return Response.status(Status.GONE).build();   
  6.   
  7. }   

六、javax.ws.rs.core.GenericEntity

 

当处理Response的返回对象(entity)时,如果是一个类似于MessageBodyWriter这样的支持泛型的对象,则问题来了: isWriteable()方法需要有泛弄的信息。然后不幸的是java的泛型信息只存在编译时,不存在运行时,因此没有一个简单的方法可以得到在运行时得到泛型的信息,因此MessageBodyWriter不知道如何输出对象。

 

为了解决这个问题,JAX-RS提供了一个帮助类 javax.ws.rs.core.GenericEntity 。例如:

Java代码 复制代码 收藏代码
  1. @GET  
  2. @Produces("application/xml")   
  3. public Response getCustomerList() {   
  4.     List<Customer> list = new ArrayList<Customer>();   
  5.     list.add(new Customer(...));   
  6.     GenericEntity entity = new GenericEntity<List<Customer>>(list){};   
  7.     return Response.ok(entity);   
  8. }  

GenericEntity也是一个泛型模板,只需要将输出entity的泛型信息加到它上,并且把对象做为一个参数传入即可。

 

七、javax.ws.rs.WebApplicationException

 

WebApplicationException是一个内置、非检测异常,支持传入Response对象或者状态码:

 

Java代码 复制代码 收藏代码
  1. public class WebApplicationException extends RuntimeException {   
  2.   
  3.     public WebApplicationException() {...}   
  4.     public WebApplicationException(Response response) {...}   
  5.     public WebApplicationException(int status) {...}   
  6.     public WebApplicationException(Response.Status status) {...}   
  7.     public WebApplicationException(Throwable cause) {...}   
  8.     public WebApplicationException(Throwable cause,   
  9.                             Response response) {...}   
  10.     public WebApplicationException(Throwable cause, int status) {...}   
  11.     public WebApplicationException(Throwable cause,   
  12.     Response.Status status) {...}   
  13.     public Response getResponse() {...]   
  14. }   

当JAX-RS碰到一个WebApplicationException抛出时,它就捕获这个异常,调用它的getResponse()方法去获取Response,发回给client端。 如果应用以一个状态码或者Response初始化了WebApplicationException,则这个状态码或者Response将被用来创建真正的HTTP响应;或者,会直接返回 500, “Internal Server Error“给客户端,例如:

 

Java代码 复制代码 收藏代码
  1. @Path("/customers")   
  2. public class CustomerResource {   
  3.   
  4.     @GET  
  5.     @Path("{id}")   
  6.     @Produces("application/xml")   
  7.     public Customer getCustomer(@PathParam("id"int id) {   
  8.         Customer cust = findCustomer(id);   
  9.         if (cust == null) {   
  10.             throw new WebApplicationException(Response.Status.NOT_FOUND);   
  11.         }   
  12.         return cust;   
  13.     }   
  14. }  

这里如果没找着客户,会返回404错误

 

八、错误匹配

 

应用中可能有各种各样的,来自应用或者第三方包的异常,如果仅依赖于容器提供的错误处理方式,则可能灵活度不够: 捕获这些异常,然后包装到WebApplicationException中会让人觉得相当乏味。

 

这里的另外一种选择就是使用javax.ws.rs.ext.ExceptionMapper,这个对象知道怎么匹配一个抛出的异常到一个Repsonse对象上:

Java代码 复制代码 收藏代码
  1. public interface ExceptionMapper<E extends Throwable> {   
  2.     Response toResponse(E exception);   
  3. }  

例如对于JPA有EntityNotFoundException:

Java代码 复制代码 收藏代码
  1. @Provider  
  2. public class EntityNotFoundMapper   
  3. implements ExceptionMapper<EntityNotFoundException> {   
  4.        
  5.       public Response toResponse(EntityNotFoundException e) {   
  6.            return Response.status(Response.Status.NOT_FOUND).build();   
  7.       }   
  8. }  

注: ExceptionMapper的实现,必须加上@Provider注释

  

ExceptionMapper也支持异常层级关系,例如A 继承 B,如果找不到A的mapper,则会向上查找B的mapper。

 

最后ExceptionMapper使用JAX-RS的deployment API进行注册,可以用Application.

分享到:
评论

相关推荐

    JAX-RS入门jar包集合

    本资源“JAX-RS入门jar包集合”包含了开始学习和使用JAX-RS所需的基本库文件,这些jar包将帮助开发者快速搭建REST服务环境。下面我们将详细讲解JAX-RS的核心概念和关键组件,以及如何利用这些jar包进行实际开发。 1...

    CursoWebServices:Curso Java Web服务JAX-WS JAX-RS

    5. JAX-RS进阶:深入研究响应式编程、客户端API、资源分页和过滤,以及与其他JAX-RS规范如JAX-RPC和JSON-P的集成。 6. 开发工具与环境:设置和使用IDE(如Eclipse或IntelliJ IDEA)、Maven或Gradle构建工具,以及...

    quick-start-jax-rs

    【快速入门JAX-RS】 JAX-RS是Java API for RESTful Web Services的缩写,它是Java平台上的一个标准,用于构建RESTful Web服务。REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,...

    cxf入门文档资料

    2. **JAX-WS与JAX-RS**:JAX-WS用于构建基于SOAP的Web服务,而JAX-RS则用于构建RESTful服务。CXF支持这两种Java API,使得开发者可以根据项目需求选择适合的服务模型。 3. **客户端开发**:在“手持客户端开发资料...

    初级Webservice教程代码资料(java)

    4. JAX-RS教程:JAX-RS利用HTTP方法(如GET、POST、PUT和DELETE)和资源URI来处理请求。学习如何使用@Path、@GET、@POST等注解创建REST服务,并理解JSON和XML之间的转换。 5. 客户端调用:无论是SOAP还是REST服务,...

    hello-world-apis:API API de grafos的世界您好

    1. **Servlet和JAX-RS**:Java中的API通常通过HTTP服务器进行通信,这可能需要使用Servlet或JAX-RS(Java API for RESTful Web Services)来创建RESTful API。Servlet处理HTTP请求,而JAX-RS则简化了创建REST服务的...

    java restFull及示例和Maven.rar

    - Jersey是JAX-RS(Java API for RESTful Web Services)的参考实现,用于创建RESTful服务。 - 注解驱动:使用@Path、@GET、@POST等注解来标记资源类和方法。 - 使用Response和Entity:返回HTTP响应,包括状态码...

    Web Service 入门

    Java中,JAX-RS(Java API for RESTful Web Services)是用于构建RESTful服务的标准API。 - 定义资源类:创建Java类表示资源,并使用`@Path`注解指定资源路径。 - 方法注解:在类的方法上使用`@GET`, `@POST`, `@...

    jaxws的小demo

    而与RESTful服务(JAX-RS)相比,JAX-WS更适合于复杂的、基于消息交换模式的服务。 通过这个"jaxws的小demo",开发者可以快速入门JAX-WS,了解其基本用法和流程,为进一步深入学习和实践Web服务开发打下基础。在...

    webservice入门教程

    2. JAX-RS:Java API for RESTful Web Services,提供了一种简化的方式来创建RESTful Web服务。 3. .NET中的Web服务:Microsoft提供了ASMX和WCF(Windows Communication Foundation)框架,用于构建和消费Web服务。 ...

    酒店系统java源码-IBM-Ready-App-for-Travel:IBMReadyAppforTravel&Transportation

    JAX-RS 项目的 WebSphere Liberty 项目。 /travel-businessrules包含将折扣应用于合作酒店预订的规则和规则流。 /travel-businessrules-app包含由业务规则构建的关联应用程序。 该应用程序部署在云中以在 BlueMix 上...

    JavaEE-7-Samples:所有 Java EE6 和 7 示例

    Java EE 7增强了JAX-RS 2.0,包括支持超媒体链接和更强大的异常处理。 通过"JavaEE-7-Samples"项目,开发者可以学习到如何在实际环境中应用这些技术,从而提升他们的Java EE开发技能。每个示例都会包含详细的代码和...

    基于CXF构建SOA例子代码

    CXF是一个开源项目,它提供了多种方式来创建和消费Web服务,包括Java API for Web Services (JAX-WS) 和Java API for RESTful Web Services (JAX-RS)。这个例子代码旨在帮助用户深入理解CXF的工作原理以及在实际项目...

    java rest简单实例,新手入门

    这个新手入门实例将帮助你理解如何使用Java和JAX-RS构建RESTful服务。通过实践,你可以更深入地学习如何处理请求参数、返回响应、使用实体类、异常处理、JSON序列化和反序列化等内容。同时,还可以探索更高级的主题...

    使用NetBeansIDE5.0开发Web服务的快速入门指南

    在NetBeans 5.0中,你可以创建基于WSDL(Web服务描述语言)的SOAP服务,或者利用JAX-RS(Java API for RESTful Web Services)来构建RESTful服务。 2. **NetBeans IDE 5.0界面**: NetBeans IDE 5.0提供了一个直观...

    开源bbs源码java-srb4j:一个JavaRESTFul后端框架,支持用户/密码/访问令牌

    开源bbs java java Srb4j = 用于 Java 的简单 RESTFul ...堆栈:JAX-RS + Spring + MyBatis + MySQL 开箱即用的后台门户 先决条件 JDK 8+ Maven 3.1+ MySQL 服务器 5.7+ 开发环境中的快速入门 生成 Java

    webService入门教程_java_webservice_

    【标题】:WebService入门教程 - Java WebService 【描述】:本教程旨在引导初学者了解如何使用Eclipse集成开发环境来发布基于Java语言的WebServices服务。WebServices是一种允许不同系统之间进行交互和数据交换的...

    Java_快速入门演示了JBoss EAP Jakarta EE 10和一些其他技术,它们提供了小的特定工作示例,可以.zip

    - **RESTful服务**:使用JAX-RS创建API并测试响应。 - **微服务**:可能包含如何将大型应用拆分为独立的服务。 `jboss-eap-quickstarts_8.0.x.zip`文件很可能是JBoss EAP 8.0的快速启动项目集合,这些项目提供了预...

    CXF入门实例

    - 使用CXF,可以通过Java API for RESTful Web Services (JAX-RS)轻松地创建RESTful服务。开发者可以使用`@Path`、`@GET`、`@POST`等注解来定义资源和操作。 - 对于SOAP服务,CXF支持JAX-WS,允许通过Java注解或者...

Global site tag (gtag.js) - Google Analytics