Introduce HttpStatusCode interface
This commit introduces HttpStatusCode, an interface implemented by HttpStatus. Instances of HttpStatusCode are obtained via static valueOf(int) factory method, returning a HttpStatus enum entry if available, and a default implementation otherwise. The underlying reason behind this change is HTTP status codes are not enumerable, but instead range from 100-999. Closes gh-28214
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2002-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.http;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Default implementation of {@link HttpStatusCode}.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 6.0
|
||||
*/
|
||||
final class DefaultHttpStatusCode
|
||||
implements HttpStatusCode, Comparable<HttpStatusCode>, Serializable {
|
||||
|
||||
private static final long serialVersionUID = 7017664779360718111L;
|
||||
|
||||
private final int value;
|
||||
|
||||
|
||||
public DefaultHttpStatusCode(int value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is1xxInformational() {
|
||||
return hundreds() == 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is2xxSuccessful() {
|
||||
return hundreds() == 2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is3xxRedirection() {
|
||||
return hundreds() == 3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is4xxClientError() {
|
||||
return hundreds() == 4;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean is5xxServerError() {
|
||||
return hundreds() == 5;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isError() {
|
||||
int hundreds = hundreds();
|
||||
return hundreds == 4 || hundreds == 5;
|
||||
}
|
||||
|
||||
private int hundreds() {
|
||||
return this.value / 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(@NotNull HttpStatusCode o) {
|
||||
return Integer.compare(this.value, o.value());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof HttpStatusCode other) {
|
||||
return this.value == other.value();
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return Integer.toString(this.value);
|
||||
}
|
||||
}
|
||||
@@ -31,7 +31,7 @@ import org.springframework.lang.Nullable;
|
||||
* @see <a href="https://www.iana.org/assignments/http-status-codes">HTTP Status Code Registry</a>
|
||||
* @see <a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes">List of HTTP status codes - Wikipedia</a>
|
||||
*/
|
||||
public enum HttpStatus {
|
||||
public enum HttpStatus implements HttpStatusCode {
|
||||
|
||||
// 1xx Informational
|
||||
|
||||
@@ -436,9 +436,7 @@ public enum HttpStatus {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return the integer value of this status code.
|
||||
*/
|
||||
@Override
|
||||
public int value() {
|
||||
return this.value;
|
||||
}
|
||||
@@ -458,70 +456,32 @@ public enum HttpStatus {
|
||||
return this.reasonPhrase;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this status code is in the HTTP series
|
||||
* {@link org.springframework.http.HttpStatus.Series#INFORMATIONAL}.
|
||||
* <p>This is a shortcut for checking the value of {@link #series()}.
|
||||
* @since 4.0
|
||||
* @see #series()
|
||||
*/
|
||||
@Override
|
||||
public boolean is1xxInformational() {
|
||||
return (series() == Series.INFORMATIONAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this status code is in the HTTP series
|
||||
* {@link org.springframework.http.HttpStatus.Series#SUCCESSFUL}.
|
||||
* <p>This is a shortcut for checking the value of {@link #series()}.
|
||||
* @since 4.0
|
||||
* @see #series()
|
||||
*/
|
||||
@Override
|
||||
public boolean is2xxSuccessful() {
|
||||
return (series() == Series.SUCCESSFUL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this status code is in the HTTP series
|
||||
* {@link org.springframework.http.HttpStatus.Series#REDIRECTION}.
|
||||
* <p>This is a shortcut for checking the value of {@link #series()}.
|
||||
* @since 4.0
|
||||
* @see #series()
|
||||
*/
|
||||
@Override
|
||||
public boolean is3xxRedirection() {
|
||||
return (series() == Series.REDIRECTION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this status code is in the HTTP series
|
||||
* {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR}.
|
||||
* <p>This is a shortcut for checking the value of {@link #series()}.
|
||||
* @since 4.0
|
||||
* @see #series()
|
||||
*/
|
||||
@Override
|
||||
public boolean is4xxClientError() {
|
||||
return (series() == Series.CLIENT_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this status code is in the HTTP series
|
||||
* {@link org.springframework.http.HttpStatus.Series#SERVER_ERROR}.
|
||||
* <p>This is a shortcut for checking the value of {@link #series()}.
|
||||
* @since 4.0
|
||||
* @see #series()
|
||||
*/
|
||||
@Override
|
||||
public boolean is5xxServerError() {
|
||||
return (series() == Series.SERVER_ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this status code is in the HTTP series
|
||||
* {@link org.springframework.http.HttpStatus.Series#CLIENT_ERROR} or
|
||||
* {@link org.springframework.http.HttpStatus.Series#SERVER_ERROR}.
|
||||
* <p>This is a shortcut for checking the value of {@link #series()}.
|
||||
* @since 5.0
|
||||
* @see #is4xxClientError()
|
||||
* @see #is5xxServerError()
|
||||
*/
|
||||
@Override
|
||||
public boolean isError() {
|
||||
return (is4xxClientError() || is5xxServerError());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2002-2021 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.http;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Represents an HTTP response status code. Implemented by {@link HttpStatus},
|
||||
* but defined as interface to allow for values not in that enumeration.
|
||||
*
|
||||
* @author Arjen Poutsma
|
||||
* @since 6.0
|
||||
* @see <a href="https://www.iana.org/assignments/http-status-codes">HTTP Status Code Registry</a>
|
||||
* @see <a href="https://en.wikipedia.org/wiki/List_of_HTTP_status_codes">List of HTTP status codes - Wikipedia</a>
|
||||
*/
|
||||
public sealed interface HttpStatusCode permits DefaultHttpStatusCode, HttpStatus {
|
||||
|
||||
/**
|
||||
* Return the integer value of this status code.
|
||||
*/
|
||||
int value();
|
||||
|
||||
/**
|
||||
* Whether this status code is in the Informational class ({@code 1xx}).
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc2616#section-10.1">RFC 2616</a>
|
||||
*/
|
||||
boolean is1xxInformational();
|
||||
|
||||
/**
|
||||
* Whether this status code is in the Successful class ({@code 2xx}).
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc2616#section-10.2">RFC 2616</a>
|
||||
*/
|
||||
boolean is2xxSuccessful();
|
||||
|
||||
/**
|
||||
* Whether this status code is in the Redirection class ({@code 3xx}).
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc2616#section-10.3">RFC 2616</a>
|
||||
*/
|
||||
boolean is3xxRedirection();
|
||||
|
||||
/**
|
||||
* Whether this status code is in the Client Error class ({@code 4xx}).
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc2616#section-10.4">RFC 2616</a>
|
||||
*/
|
||||
boolean is4xxClientError();
|
||||
|
||||
/**
|
||||
* Whether this status code is in the Server Error class ({@code 5xx}).
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc2616#section-10.5">RFC 2616</a>
|
||||
*/
|
||||
boolean is5xxServerError();
|
||||
|
||||
/**
|
||||
* Whether this status code is in the Client or Server Error class
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc2616#section-10.4">RFC 2616</a>
|
||||
* @see <a href="https://datatracker.ietf.org/doc/html/rfc2616#section-10.3">RFC 2616</a>
|
||||
* ({@code 4xx} or {@code 5xx}).
|
||||
* @see #is4xxClientError()
|
||||
* @see #is5xxServerError()
|
||||
*/
|
||||
boolean isError();
|
||||
|
||||
|
||||
/**
|
||||
* Return an {@code HttpStatusCode} object for the given integer value.
|
||||
* @param code the status code as integer
|
||||
* @return the corresponding {@code HttpStatusCode}
|
||||
* @throws IllegalArgumentException if {@code code} is not a three-digit
|
||||
* positive number
|
||||
*/
|
||||
static HttpStatusCode valueOf(int code) {
|
||||
Assert.isTrue(code >= 100 && code <= 999, "Code '" + code + "' should be a thee-digit positive integer");
|
||||
HttpStatus status = HttpStatus.resolve(code);
|
||||
if (status != null) {
|
||||
return status;
|
||||
}
|
||||
else {
|
||||
return new DefaultHttpStatusCode(code);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user