JAX-RS中请求与响应头的处理技巧

在Java EE中,JAX-RS(Java API for RESTful Web Services)是一个用于构建RESTful Web服务的强大框架。它提供了多种方式来处理HTTP请求和响应头,这在开发RESTful API时非常有用。本文将通过一系列实例,详细介绍如何在JAX-RS中访问请求头以及如何设置响应头。
一、访问请求头
(一)使用HttpHeaders
HttpHeaders接口提供了对请求头的全面访问。通过@Context注解,我们可以将HttpHeaders注入到资源类中,从而获取所有请求头信息。以下是一个示例:
java复制
@Path(“/”)
public class TestResource {
@GET
@Path(“test1”)
public String allHeaders(@Context HttpHeaders headers) {
MultivaluedMap rh = headers.getRequestHeaders();
String str = rh.entrySet()
.stream()
.map(e -> e.getKey() + " = " + e.getValue())
.collect(Collectors.joining(“
”));
return str;
}
}
在这个例子中,我们通过headers.getRequestHeaders()获取了所有请求头,并将其格式化为字符串返回。运行此服务后,使用HTTP客户端(如HTTPie)发送请求,即可看到返回的请求头信息。
HttpHeaders还提供了一些强类型的方法来获取特定的请求头,例如getAcceptableLanguages()、getCookies()等。以下是一个获取Accept-Language请求头的示例:
java复制
@Path(“/”)
public class TestResource {
@GET
@Path(“test2”)
public String acceptableLanguages(@Context HttpHeaders headers) {
List locales = headers.getAcceptableLanguages();
return locales.stream()
.map(l -> l.toString())
.collect(Collectors.joining(“
”));
}
}
(二)使用@HeaderParam
@HeaderParam注解可以将请求头的值直接绑定到资源方法的参数中。这使得代码更加简洁,也便于直接操作请求头的值。例如:
java复制
@Path(“/”)
public class TestResource {
@GET
@Path(“test3”)
public String requestParamTest1(@HeaderParam(HttpHeaders.HOST) String host) {
return "The request ‘host’ header value = " + host;
}
}
在这个例子中,@HeaderParam(HttpHeaders.HOST)将请求头中的Host字段值绑定到了host参数中,我们直接在方法中使用这个参数即可。
(三)自动类型绑定
JAX-RS能够将请求头字符串自动绑定到合适的Java类型。以下是一些常见的绑定方式:

  1. 绑定到Java基本类型
    java复制
    @Path(“/”)
    public class TestResource {
    @GET
    @Path(“test4”)
    public String requestParamTest2(@HeaderParam(“anInt”) int anInteger) {
    return "The request header ‘anInt’ value: " + anInteger;
    }
    }
    在这个例子中,请求头anInt的值被自动解析为int类型。
  2. 绑定到具有String构造器的Java类型
    如果一个Java类型具有接受String作为参数的构造器,JAX-RS可以自动将其初始化。例如java.util.Date:
    java复制
    @Path(“/”)
    public class TestResource {
    @GET
    @Path(“test5”)
    public String requestParamTest3(@HeaderParam(“aDate”) Date date) {
    return "The request header ‘aDate’ value: " + date;
    }
    }
  3. 绑定到具有valueOf(String)方法的类型
    如果一个类型具有valueOf(String)方法,JAX-RS也可以将其自动绑定。例如:
    java复制
    public class DateInfo {
    private Date date;
    public static DateInfo valueOf(String dateStr) {
    if(dateStr == null) {
    return null;
    }
    DateInfo dateInfo = new DateInfo();
    dateInfo.date = new Date(dateStr);
    return dateInfo;
    }
    public LocalDateTime asLocalDateTime() {
    return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
    }
    public Date asDate() {
    return date;
    }
    }

@Path(“/”)
public class TestResource {
@GET
@Path(“test6”)
public String valueOfTest(@HeaderParam(“aDate”) DateInfo dateInfo) {
return "The request header ‘aDate’ converted to LocalDateTime: " +
dateInfo.asLocalDateTime();
}
}
4. 绑定到实现ParamConverter的类型
通过实现ParamConverter接口,我们可以自定义类型转换逻辑。以下是一个将LocalDateTime作为请求头参数的示例:
java复制
public class MyDateConverter implements ParamConverter {
@Override
public LocalDateTime fromString(String value) {
Date date = new Date(value);
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
@Override
public String toString(LocalDateTime value) {
return value.toString();
}
}

@Provider
public class MyDateConverterProvider implements ParamConverterProvider {
@Override
public ParamConverter getConverter(Class rawType, Type genericType,
Annotation[] annotations) {
if (rawType == LocalDateTime.class) {
return (ParamConverter) new MyDateConverter();
}
return null;
}
}

@Path(“/”)
public class TestResource {
@GET
@Path(“test7”)
public String paramConverterTest(@HeaderParam(“aDate”) LocalDateTime date) {
return “The request header ‘aDate’ converted by MyDateConverter: " + date;
}
}
5. 绑定到Collection
我们还可以将请求头绑定到java.util.Collection类型,例如List或Set。以下是一个示例:
java复制
@Path(”/“)
public class TestResource {
@GET
@Path(“test8”)
public String collectionTest(@HeaderParam(“myHeader”) List list) {
String rv = “header collection values: \n”;
rv += list.stream()
.map(Object::toString)
.collect(Collectors.joining(”\n"));
return rv;
}
}
二、返回响应头
如果需要在响应中添加额外的元数据,可以返回一个Response实例。ResponseBuilder类提供了一种便捷的方式来构建Response对象。以下是一个示例:
java复制
@Path(“/”)
public class TestResource {
@GET
@Path(“test10”)
public Response responseHeaderTest1() {
Response.ResponseBuilder rb = Response.ok(“the test response”);
Response response = rb.header(“header1”, “value1”)
.header(“header2”, “value2”)
.build();
return response;
}
}
在这个例子中,我们通过ResponseBuilder添加了两个自定义响应头header1和header2。
三、使用JAX-RS客户端发送请求头
JAX-RS客户端API也支持在发送请求时添加请求头。以下是一个示例:
java复制
public class MyClient {
public static void main(String[] args) {
Client client = ClientBuilder.newClient();
WebTarget target = client.target(“http://localhost:8080/test11”);
Invocation.Builder builder = target.request();
String response = builder.header(“myHeader”, “a”)
.header(“aDateHeader”, new Date())
.get(String.class);
System.out.println(response);
client.close();
}
}
在这个例子中,我们通过Invocation.Builder的header方法添加了两个自定义请求头myHeader和aDateHeader。
四、总结
JAX-RS提供了强大的机制来处理请求和响应头。通过HttpHeaders接口、@HeaderParam注解以及自动类型绑定等功能,我们可以轻松地访问和操作请求头。同时,ResponseBuilder类也使得构建带有自定义响应头的响应变得非常简单。掌握这些技巧,将有助于我们开发更加灵活和功能丰富的RESTful Web服务。

你可能感兴趣的:(python,开发语言,个人开发)