43 headers = normalizeHeaders(headers);
44 body = body ==
null ?
new byte[0] : body.clone();
47 public static Builder builder(
final HttpMethod method,
final URI uri) {
48 return new Builder(method, uri);
51 public static Builder
get(
final URI uri) {
55 public static Builder post(
final URI uri) {
59 public static Builder put(
final URI uri) {
63 public static Builder patch(
final URI uri) {
67 public static Builder delete(
final URI uri) {
71 public String bodyAsString() {
72 return new String(body, StandardCharsets.UTF_8);
75 private static Map<String, List<String>> normalizeHeaders(
final Map<String, List<String>> raw) {
76 if (raw ==
null || raw.isEmpty()) {
79 final var copy =
new LinkedHashMap<String, List<String>>();
80 for (
final var entry : raw.entrySet()) {
81 copy.put(entry.getKey(), List.copyOf(entry.getValue()));
83 return Map.copyOf(copy);
86 public static final class Builder {
88 private final URI uri;
89 private final Map<String, List<String>> headers =
new LinkedHashMap<>();
91 private Duration timeout;
92 private String contentType;
94 private Builder(
final HttpMethod method,
final URI uri) {
99 public Builder header(
final String name,
final String value) {
100 headers.computeIfAbsent(name, key ->
new ArrayList<>()).add(value);
104 public Builder contentType(
final String contentType) {
105 this.contentType = contentType;
109 public Builder body(
final byte[] body) {
110 this.body = body ==
null ? null : body.clone();
114 public Builder body(
final String content) {
115 this.body = content ==
null ? null : content.getBytes(StandardCharsets.UTF_8);
119 public Builder jsonBody(
final Object value) {
121 this.contentType =
"application/json";
125 public Builder jsonBody(
final Object value,
final dev.rafex.ether.json.JsonCodec codec) {
126 this.body = (codec ==
null ?
JsonUtils.
codec() : codec).toJsonBytes(value);
127 this.contentType =
"application/json";
131 public Builder timeout(
final Duration timeout) {
132 this.timeout = timeout;
137 if (contentType !=
null && !headers.containsKey(
"Content-Type")) {
138 header(
"Content-Type", contentType);