diff --git a/spring-web/src/main/java/org/springframework/http/DefaultHttpStatusCode.java b/spring-web/src/main/java/org/springframework/http/DefaultHttpStatusCode.java new file mode 100644 index 00000000000..46dbeaf1932 --- /dev/null +++ b/spring-web/src/main/java/org/springframework/http/DefaultHttpStatusCode.java @@ -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, 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); + } +} diff --git a/spring-web/src/main/java/org/springframework/http/HttpStatus.java b/spring-web/src/main/java/org/springframework/http/HttpStatus.java index 486b524df91..af1d1876dd1 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpStatus.java +++ b/spring-web/src/main/java/org/springframework/http/HttpStatus.java @@ -31,7 +31,7 @@ import org.springframework.lang.Nullable; * @see HTTP Status Code Registry * @see List of HTTP status codes - Wikipedia */ -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}. - *

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}. - *

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}. - *

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}. - *

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}. - *

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}. - *

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()); } diff --git a/spring-web/src/main/java/org/springframework/http/HttpStatusCode.java b/spring-web/src/main/java/org/springframework/http/HttpStatusCode.java new file mode 100644 index 00000000000..4f76278e693 --- /dev/null +++ b/spring-web/src/main/java/org/springframework/http/HttpStatusCode.java @@ -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 HTTP Status Code Registry + * @see List of HTTP status codes - Wikipedia + */ +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 RFC 2616 + */ + boolean is1xxInformational(); + + /** + * Whether this status code is in the Successful class ({@code 2xx}). + * @see RFC 2616 + */ + boolean is2xxSuccessful(); + + /** + * Whether this status code is in the Redirection class ({@code 3xx}). + * @see RFC 2616 + */ + boolean is3xxRedirection(); + + /** + * Whether this status code is in the Client Error class ({@code 4xx}). + * @see RFC 2616 + */ + boolean is4xxClientError(); + + /** + * Whether this status code is in the Server Error class ({@code 5xx}). + * @see RFC 2616 + */ + boolean is5xxServerError(); + + /** + * Whether this status code is in the Client or Server Error class + * @see RFC 2616 + * @see RFC 2616 + * ({@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); + } + } + +}