View Javadoc
1   package cn.home1.oss.lib.errorhandle.internal;
2   
3   import static cn.home1.oss.lib.errorhandle.api.ExceptionResolver.COMPOSITE_EXCEPTION_RESOLVER;
4   
5   import com.google.common.collect.ImmutableMap;
6   
7   import cn.home1.oss.lib.errorhandle.api.ExceptionResolver;
8   import cn.home1.oss.lib.errorhandle.api.ResolvedError;
9   import cn.home1.oss.lib.errorhandle.api.ResolvedErrorException;
10  
11  import lombok.Setter;
12  
13  import org.springframework.beans.factory.annotation.Autowired;
14  import org.springframework.beans.factory.annotation.Qualifier;
15  import org.springframework.boot.autoconfigure.web.ErrorAttributes;
16  import org.springframework.core.Ordered;
17  import org.springframework.core.annotation.Order;
18  import org.springframework.web.context.request.RequestAttributes;
19  import org.springframework.web.servlet.HandlerExceptionResolver;
20  import org.springframework.web.servlet.ModelAndView;
21  
22  import java.util.Map;
23  
24  import javax.servlet.http.HttpServletRequest;
25  import javax.servlet.http.HttpServletResponse;
26  
27  /**
28   * {@link org.springframework.boot.autoconfigure.web.DefaultErrorAttributes}
29   *
30   * <p>
31   * Created by zhanghaolun on 16/8/9.
32   * </p>
33   */
34  @Order(Ordered.HIGHEST_PRECEDENCE)
35  public class ExtendedErrorAttributes //
36    implements ErrorAttributes, HandlerExceptionResolver, Ordered {
37  
38    private static final String ERROR_ATTRIBUTE = ExtendedErrorAttributes.class.getName() + ".ERROR";
39  
40    @Qualifier(COMPOSITE_EXCEPTION_RESOLVER)
41    @Autowired
42    @Setter
43    private ExceptionResolver<Throwable> resolver;
44  
45    @Override
46    public Map<String, Object> getErrorAttributes( //
47      final RequestAttributes requestAttributes, //
48      final boolean includeStackTrace //
49    ) {
50      final Throwable error = getError(requestAttributes);
51      final ResolvedError resolved = ResolvedErrorException.isResolvedError(error) ? //
52        ((ResolvedErrorException) error).getError() : //
53        this.resolver.resolve(requestAttributes, error);
54      return resolved != null ? resolved.toErrorAttributes() : ImmutableMap.of();
55    }
56  
57    @Override
58    public int getOrder() {
59      return Ordered.HIGHEST_PRECEDENCE;
60    }
61  
62    @Override
63    public ModelAndView resolveException( //
64      final HttpServletRequest request, //
65      final HttpServletResponse response, //
66      final Object handler, //
67      final Exception ex //
68    ) {
69      final ResolvedError resolved = this.resolver.resolve(request, ex);
70      this.storeErrorAttributes(request, resolved != null ? new ResolvedErrorException(resolved) : ex);
71      return null;
72    }
73  
74    private void storeErrorAttributes(final HttpServletRequest request, final Exception ex) {
75      request.setAttribute(ERROR_ATTRIBUTE, ex);
76    }
77  
78    @Override
79    public Throwable getError(final RequestAttributes requestAttributes) {
80      final Throwable found = getAttribute(requestAttributes, ERROR_ATTRIBUTE);
81      return found != null ? found : getAttribute(requestAttributes, "javax.servlet.error.exception");
82    }
83  
84    @SuppressWarnings("unchecked")
85    private <T> T getAttribute(final RequestAttributes requestAttributes, final String name) {
86      return (T) requestAttributes.getAttribute(name, RequestAttributes.SCOPE_REQUEST);
87    }
88  }