001/* 002 * Copyright 2002-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 * https://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.remoting.support; 018 019import java.io.Serializable; 020import java.lang.reflect.InvocationTargetException; 021 022import org.springframework.lang.Nullable; 023 024/** 025 * Encapsulates a remote invocation result, holding a result value or an exception. 026 * Used for HTTP-based serialization invokers. 027 * 028 * <p>This is an SPI class, typically not used directly by applications. 029 * Can be subclassed for additional invocation parameters. 030 * 031 * <p>Both {@link RemoteInvocation} and {@link RemoteInvocationResult} are designed 032 * for use with standard Java serialization as well as JavaBean-style serialization. 033 * 034 * @author Juergen Hoeller 035 * @since 1.1 036 * @see RemoteInvocation 037 */ 038public class RemoteInvocationResult implements Serializable { 039 040 /** Use serialVersionUID from Spring 1.1 for interoperability. */ 041 private static final long serialVersionUID = 2138555143707773549L; 042 043 044 @Nullable 045 private Object value; 046 047 @Nullable 048 private Throwable exception; 049 050 051 /** 052 * Create a new RemoteInvocationResult for the given result value. 053 * @param value the result value returned by a successful invocation 054 * of the target method 055 */ 056 public RemoteInvocationResult(@Nullable Object value) { 057 this.value = value; 058 } 059 060 /** 061 * Create a new RemoteInvocationResult for the given exception. 062 * @param exception the exception thrown by an unsuccessful invocation 063 * of the target method 064 */ 065 public RemoteInvocationResult(@Nullable Throwable exception) { 066 this.exception = exception; 067 } 068 069 /** 070 * Create a new RemoteInvocationResult for JavaBean-style deserialization 071 * (e.g. with Jackson). 072 * @see #setValue 073 * @see #setException 074 */ 075 public RemoteInvocationResult() { 076 } 077 078 079 /** 080 * Set the result value returned by a successful invocation of the 081 * target method, if any. 082 * <p>This setter is intended for JavaBean-style deserialization. 083 * Use {@link #RemoteInvocationResult(Object)} otherwise. 084 * @see #RemoteInvocationResult() 085 */ 086 public void setValue(@Nullable Object value) { 087 this.value = value; 088 } 089 090 /** 091 * Return the result value returned by a successful invocation 092 * of the target method, if any. 093 * @see #hasException 094 */ 095 @Nullable 096 public Object getValue() { 097 return this.value; 098 } 099 100 /** 101 * Set the exception thrown by an unsuccessful invocation of the 102 * target method, if any. 103 * <p>This setter is intended for JavaBean-style deserialization. 104 * Use {@link #RemoteInvocationResult(Throwable)} otherwise. 105 * @see #RemoteInvocationResult() 106 */ 107 public void setException(@Nullable Throwable exception) { 108 this.exception = exception; 109 } 110 111 /** 112 * Return the exception thrown by an unsuccessful invocation 113 * of the target method, if any. 114 * @see #hasException 115 */ 116 @Nullable 117 public Throwable getException() { 118 return this.exception; 119 } 120 121 /** 122 * Return whether this invocation result holds an exception. 123 * If this returns {@code false}, the result value applies 124 * (even if it is {@code null}). 125 * @see #getValue 126 * @see #getException 127 */ 128 public boolean hasException() { 129 return (this.exception != null); 130 } 131 132 /** 133 * Return whether this invocation result holds an InvocationTargetException, 134 * thrown by an invocation of the target method itself. 135 * @see #hasException() 136 */ 137 public boolean hasInvocationTargetException() { 138 return (this.exception instanceof InvocationTargetException); 139 } 140 141 142 /** 143 * Recreate the invocation result, either returning the result value 144 * in case of a successful invocation of the target method, or 145 * rethrowing the exception thrown by the target method. 146 * @return the result value, if any 147 * @throws Throwable the exception, if any 148 */ 149 @Nullable 150 public Object recreate() throws Throwable { 151 if (this.exception != null) { 152 Throwable exToThrow = this.exception; 153 if (this.exception instanceof InvocationTargetException) { 154 exToThrow = ((InvocationTargetException) this.exception).getTargetException(); 155 } 156 RemoteInvocationUtils.fillInClientStackTraceIfPossible(exToThrow); 157 throw exToThrow; 158 } 159 else { 160 return this.value; 161 } 162 } 163 164}