001/* 002 * Copyright 2012-2018 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.web.server; 018 019import org.springframework.http.HttpStatus; 020import org.springframework.util.ObjectUtils; 021 022/** 023 * Simple server-independent abstraction for error pages. Roughly equivalent to the 024 * {@literal <error-page>} element traditionally found in web.xml. 025 * 026 * @author Dave Syer 027 * @since 2.0.0 028 */ 029public class ErrorPage { 030 031 private final HttpStatus status; 032 033 private final Class<? extends Throwable> exception; 034 035 private final String path; 036 037 public ErrorPage(String path) { 038 this.status = null; 039 this.exception = null; 040 this.path = path; 041 } 042 043 public ErrorPage(HttpStatus status, String path) { 044 this.status = status; 045 this.exception = null; 046 this.path = path; 047 } 048 049 public ErrorPage(Class<? extends Throwable> exception, String path) { 050 this.status = null; 051 this.exception = exception; 052 this.path = path; 053 } 054 055 /** 056 * The path to render (usually implemented as a forward), starting with "/". A custom 057 * controller or servlet path can be used, or if the server supports it, a template 058 * path (e.g. "/error.jsp"). 059 * @return the path that will be rendered for this error 060 */ 061 public String getPath() { 062 return this.path; 063 } 064 065 /** 066 * Returns the exception type (or {@code null} for a page that matches by status). 067 * @return the exception type or {@code null} 068 */ 069 public Class<? extends Throwable> getException() { 070 return this.exception; 071 } 072 073 /** 074 * The HTTP status value that this error page matches (or {@code null} for a page that 075 * matches by exception). 076 * @return the status or {@code null} 077 */ 078 public HttpStatus getStatus() { 079 return this.status; 080 } 081 082 /** 083 * The HTTP status value that this error page matches. 084 * @return the status value (or 0 for a page that matches any status) 085 */ 086 public int getStatusCode() { 087 return (this.status != null) ? this.status.value() : 0; 088 } 089 090 /** 091 * The exception type name. 092 * @return the exception type name (or {@code null} if there is none) 093 */ 094 public String getExceptionName() { 095 return (this.exception != null) ? this.exception.getName() : null; 096 } 097 098 /** 099 * Return if this error page is a global one (matches all unmatched status and 100 * exception types). 101 * @return if this is a global error page 102 */ 103 public boolean isGlobal() { 104 return (this.status == null && this.exception == null); 105 } 106 107 @Override 108 public boolean equals(Object obj) { 109 if (this == obj) { 110 return true; 111 } 112 if (obj == null) { 113 return false; 114 } 115 if (obj instanceof ErrorPage) { 116 ErrorPage other = (ErrorPage) obj; 117 boolean rtn = true; 118 rtn = rtn && ObjectUtils.nullSafeEquals(getExceptionName(), 119 other.getExceptionName()); 120 rtn = rtn && ObjectUtils.nullSafeEquals(this.path, other.path); 121 rtn = rtn && this.status == other.status; 122 return rtn; 123 } 124 return false; 125 } 126 127 @Override 128 public int hashCode() { 129 final int prime = 31; 130 int result = 1; 131 result = prime * result + ObjectUtils.nullSafeHashCode(getExceptionName()); 132 result = prime * result + ObjectUtils.nullSafeHashCode(this.path); 133 result = prime * result + this.getStatusCode(); 134 return result; 135 } 136 137}