# HttpStatus JSP Tag Library [![License (3-Clause BSD)](https://img.shields.io/badge/license-BSD%203--Clause-blue.svg?style=flat-square)](http://opensource.org/licenses/BSD-3-Clause) [![Java](https://img.shields.io/badge/java-17%2B-blue)](https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html) [![bld](https://img.shields.io/badge/2.2.1-FA9052?label=bld&labelColor=2392FF)](https://rife2.com/bld) [![Release](https://img.shields.io/github/release/ethauvin/httpstatus.svg)](https://github.com/ethauvin/httpstatus/releases/latest) [![Sonatype Nexus (Snapshots)](https://img.shields.io/nexus/s/net.thauvin.erik.httpstatus/httpstatus.svg?label=sanpshot&server=https%3A%2F%2Foss.sonatype.org)](https://oss.sonatype.org/content/repositories/snapshots/net/thauvin/erik/httpstatus/httpstatus/) [![Maven Central](https://img.shields.io/maven-central/v/net.thauvin.erik.httpstatus/httpstatus.svg?color=blue)](https://central.sonatype.com/artifact/net.thauvin.erik.httpstatus/httpstatus) [![Known Vulnerabilities](https://snyk.io/test/github/ethauvin/httpstatus/badge.svg?targetFile=pom.xml)](https://snyk.io/test/github/ethauvin/httpstatus?targetFile=pom.xml) [![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=ethauvin_HttpStatus&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=ethauvin_HttpStatus) [![GitHub CI](https://github.com/ethauvin/httpstatus/actions/workflows/bld.yml/badge.svg)](https://github.com/ethauvin/httpstatus/actions/workflows/bld.yml) [![CircleCI](https://circleci.com/gh/ethauvin/HttpStatus/tree/master.svg?style=shield)](https://circleci.com/gh/ethauvin/HttpStatus/tree/master) A simple [JSP](http://www.oracle.com/technetwork/java/javaee/jsp/index.html) Tag Library to display the [code](#hscode), [reason](#hsreason), [cause](#hscode) and/or [message](#hsmessage) for [HTTP status codes](http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html) in JSP error pages. ## Table of Contents - [Examples](#examples) - [Usage](#usage) - [Gradle](#gradle) - [bld](#bld) - [Maven](#maven) - [JSP Tags](#jsp-tags) - [hs:cause](#hscause) - [hs:code](#hscode) - [hs:message](#hsmessage) - [hs:reason](#hsreason) - [StatusCode Bean](#statuscode-bean) - [Reasons](#reasons) - [Command Line Usage](#command-line-usage) - [Contributing](#contributing) ## Examples For example: ```jsp <%@ page isErrorPage="true" %> <%@ taglib prefix="hs" uri="http://erik.thauvin.net/taglibs/httpstatus" %> <hs:code/> <hs:reason default="Server Error"/>

Cause:
Message:
... ``` or ```jsp <%@ page isErrorPage="true" import="net.thauvin.erik.httpstatus.Reasons" %> <%= Reasons.getReasonPhrase(pageContext.getErrorData().getStatusCode()) %> ``` would display on a [501 status code](https://www.rfc-editor.org/rfc/rfc9110.html#name-501-not-implemented): ```console Not Implemented ``` ## Usage ### [Gradle](https://gradle.org/) Include the following in your `build.gradle` file: ```gradle repositories { mavenCentral() } dependencies { implementation 'net.thauvin.erik.httpstatus:httpstatus:1.1.1' } ``` ### [bld](https://rife2.com/bld) Include the following in your `bld` build file: ```java scope(compile).include( dependency("net.thauvin.erik.httpstatus","httpstatus", version(1, 1, 0)) ); ``` ### [Maven](http://maven.apache.org/) As a `Maven` artifact: ```xml net.thauvin.erik.httpstatus httpstatus 1.1.1 ``` ## JSP Tags ### hs:cause The `` tag displays the cause of current HTTP status code, if any. A shorthand for: ```jsp <%= pageContext.getErrorData().getThrowable().getCause().getLocalizedMessage() %> ``` Optional attributes are: | Attribute | Description | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `default` | The fallback value to output, if no cause is | | `escapeXml` | Converts <, >, &, ', " to their corresponding [entity codes](http://dev.w3.org/html5/html-author/charref). Value is `true` by default. | ### hs:code The `` tag displays the current HTTP status code, if any. A shorthand for: ```jsp <%= pageContext.getErrorData().getStatusCode() %> ``` ### hs:message The `` tag displays the current error message, if any. A shorthand for: ```jsp <%= request.getAttribute("javax.servlet.error.message") %> ``` Optional attributes are: | Attribute | Description | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `default` | The fallback value to output, if no error message is available. | | `escapeXml` | Converts <, >, &, ', " to their corresponding [entity codes](http://dev.w3.org/html5/html-author/charref). Value is `true` by default. | ### hs:reason The `` tag displays the reason for an HTTP status code, if any. Optional attributes are: | Attribute | Description | | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | | `default` | The fallback value to output, if no reason is available. | | `code` | The HTTP status error code. If not specified the current status code is used. | | `escapeXml` | Converts <, >, &, ', " to their corresponding [entity codes](http://dev.w3.org/html5/html-author/charref). Value is `true` by default. | ## StatusCode Bean The `StatusCode` bean can be used to check the class of the status code error. For example, using the JSTL: ```jsp <%@ taglib prefix="hs" uri="http://erik.thauvin.net/taglibs/httpstatus" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> An error occurred on your side. () An error occurred on our side. () ``` or in a Servlet: ```java import net.thauvin.erik.httpstatus.StatusCode; public class ExampleServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) { var statusCode = new StatusCode( (Integer) request.getAttribute("javax.servlet.error.status_code")); if (statusCode.isError()) { if (statusCode.isServerError()) { var reason = statusCode.getReason(); } else { // ... } } } } ``` The `StatusCode` bean methods are: | Method | Description | | --------------- | -------------------------------------------------------------------- | | `getReason` | Returns the reason for the status code (eg: `Internal Server Error`) | | `isClientError` | Checks if the status code is a client error. | | `isError` | Checks if the status code is a server or client error. | | `isInfo` | Checks if the status code is informational. | | `isRedirect` | Checks if the status code is a redirect. | | `isServerError` | Checks if the status code is a server error. | | `isSuccess` | Checks if the status code is a success. (`OK`) | | `isValid` | Checks if the status code is valid. | ## Reasons The reasons are defined in a [ResourceBundle](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ResourceBundle.html) properties as follows: | Status Code | Reason | | ----------- | ---------------------------------------------------------- | | `100` | Continue | | `101` | Switching Protocols | | `102` | Processing | | `103` | Early Hints | | `110` | Response is Stale | | `111` | Revalidation Failed | | `112` | Disconnected Operation | | `113` | Heuristic Expiration | | `199` | Miscellaneous Warning | | `200` | OK | | `201` | Created | | `202` | Accepted | | `203` | Non-Authoritative Information | | `204` | No Content | | `205` | Reset Content | | `206` | Partial Content | | `207` | Multi-Status | | `208` | Already Reported | | `214` | Transformation Applied | | `218` | This is fine | | `226` | IM Used | | `299` | Miscellaneous Persistent Warning | | `300` | Multiple Choices | | `301` | Moved Permanently | | `302` | Found/Moved Temporarily | | `303` | See Other | | `304` | Not Modified | | `305` | Use Proxy | | `306` | Unused | | `307` | Temporary Redirect | | `308` | Permanent Redirect | | `400` | Bad Request | | `401` | Unauthorized | | `402` | Payment Required | | `403` | Forbidden | | `404` | Not Found | | `405` | Method Not Allowed | | `406` | Not Acceptable | | `407` | Proxy Authentication Required | | `408` | Request Timeout | | `409` | Conflict | | `410` | Gone | | `411` | Length Required | | `412` | Precondition Failed | | `413` | Payload Too Large | | `414` | URI Too Long | | `415` | Unsupported Media Type | | `416` | Range Not Satisfiable | | `417` | Expectation Failed | | `418` | I'm A Teapot | | `419` | Insufficient Space on Resource | | `420` | Method Failure | | `421` | Misdirected Request | | `422` | Unprocessable Content | | `423` | Locked | | `424` | Failed Dependency | | `425` | Too Early | | `426` | Upgrade Required | | `428` | Precondition Required | | `429` | Too Many Requests | | `430` | Request Header Fields Too Large | | `431` | Request Header Fields Too Large | | `440` | Login Timeout | | `444` | No Response | | `449` | Retry With | | `450` | Blocked by Windows Parental Controls | | `451` | Unavailable For Legal Reasons | | `460` | Client Closed Connection Before Load Balancer Idle Timeout | | `463` | X-Forwarded-For Header with More than 30 IP Addresses | | `494` | Request Header Too Large | | `495` | SSL Certificate Error | | `496` | SSL Certificate Required | | `497` | HTTP Request Sent to HTTPS Port | | `498` | Token Expired/Invalid | | `499` | Client Closed Request | | `500` | Internal Server Error | | `501` | Not Implemented | | `502` | Bad Gateway | | `503` | Service Unavailable | | `504` | Gateway Timeout | | `505` | HTTP Version Not Supported | | `506` | Variant Also Negotiates | | `507` | Insufficient Storage | | `508` | Loop Detected | | `509` | Bandwidth Limit Exceeded | | `510` | Not Extended | | `511` | Network Authentication Required | | `520` | Unknown Error | | `521` | Web Server Is Down | | `522` | Connection Timed Out | | `523` | Origin Is Unreachable | | `524` | A Timeout Occurred | | `525` | SSL Handshake Failed | | `526` | Invalid SSL Certificate | | `527` | Railgun Error | | `529` | Site is overloaded | | `530` | Site is frozen | | `540` | Temporarily Disabled | | `561` | Unauthorized | | `598` | Network Read Timeout Error | | `599` | Network Connect Timeout Error | | `783` | Unexpected Token | ## Command Line Usage You can query the reason phrase for status codes as follows: ```console $ java -jar httpstatus-1.1.1.jar 404 500 404: Not Found 500: Internal Server Error ``` If no status code is specified, all will be printed: ```console $ java -jar httpstatus-1.1.1.jar 100: Continue 101: Switching Protocols 102: Processing 103: Early Hints 110: Response is Stale 111: Revalidation Failed 112: Disconnected Operation 113: Heuristic Expiration 199: Miscellaneous Warning 200: OK 201: Created 202: Accepted 203: Non-Authoritative Information ... ``` You can also print status codes by [response classes](https://www.rfc-editor.org/rfc/rfc9110.html#name-status-codes): ```console $ java -jar httpstatus-1.1.1.jar 2xx 200: OK 201: Created 202: Accepted 203: Non-Authoritative Information ... ``` ## Contributing If you want to contribute to this project, all you have to do is clone the GitHub repository: ```console git clone git@github.com:ethauvin/HttpStatus.git ``` Then use [bld](https://rife2.com/bld) to build: ```console cd HttpStatus ./bld compile ``` The project has an [IntelliJ IDEA](https://www.jetbrains.com/idea/) project structure. You can just open it after all the dependencies were downloaded and peruse the code.