Spring 源码解析七:异样解决与视图解析

接着上一篇,讲一下剩下的几个策略

  • 把 ExceptionHandlerExceptionResolver
    、ResponseStatusExceptionResolver
    、DefaultHandlerExceptionResolver
    作为默认的处理器异样解析器
  • 把 DefaultRequestToViewNameTranslator
    作为默认的视图查找处理器
  • 把 InternalResourceViewResolver
    作为默认的视图解析器

另外,View.render 视图渲染也在这里讲一下

1. ExceptionHandlerExceptionResolver

ExceptionHandlerExceptionResolver
的次要性能是解析处理器调用产生的异样

继承关系如下

- AbstractHandlerExceptionResolver  - AbstractHandlerMethodExceptionResolver    - ExceptionHandlerExceptionResolver

1.1. AbstractHandlerExceptionResolver

AbstractHandlerExceptionResolver
的次要性能是能够设置异样处理器

public abstract class AbstractHandlerExceptionResolver implements HandlerExceptionResolver, Ordered {    // 设置自定义处理器    public void setMappedHandlers(Set<?> mappedHandlers) {        this.mappedHandlers = mappedHandlers;    }    // 设置自定义处理器类    public void setMappedHandlerClasses(Class<?>... mappedHandlerClasses) {        this.mappedHandlerClasses = mappedHandlerClasses;    }    // 解析异样    public ModelAndView resolveException(            HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {        // 查看是否可利用处理器        if (shouldApplyTo(request, handler)) {            // 解析异样,调用处理器解决            ModelAndView result = doResolveException(request, response, handler, ex);            // ... 代码省略            return result;        }        else {            return null;        }    }}
public abstract class AbstractHandlerExceptionResolver implements HandlerExceptionResolver, Ordered {    // 查看是否可利用处理器    protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) {        if (handler != null) {            // 如果蕴含在mappedHandlers中,能够解决            if (this.mappedHandlers != null && this.mappedHandlers.contains(handler)) {                return true;            }            // 如果蕴含在mappedHandlerClasses中,能够解决            if (this.mappedHandlerClasses != null) {                for (Class<?> handlerClass : this.mappedHandlerClasses) {                    if (handlerClass.isInstance(handler)) {                        return true;                    }                }            }        }        // 如果没有mappedHandlers与mappedHandlerClasses,默认能够应用        return !hasHandlerMappings();    }    // 解析异样,调用处理器解决,子类实现    protected abstract ModelAndView doResolveException(            HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex);}

1.2. AbstractHandlerMethodExceptionResolver

AbstractHandlerMethodExceptionResolver
的次要性能是能够通过异样类型来解决

public abstract class AbstractHandlerMethodExceptionResolver extends AbstractHandlerExceptionResolver {    // 查看是否可利用处理器    @Override    protected boolean shouldApplyTo(HttpServletRequest request, @Nullable Object handler) {        if (handler == null) {            return super.shouldApplyTo(request, null);        }        // 如果是,获取HandlerMethod外部的handler,持续判断        else if (handler instanceof HandlerMethod) {            HandlerMethod handlerMethod = (HandlerMethod) handler;            handler = handlerMethod.getBean();            return super.shouldApplyTo(request, handler);        }        // 如果有全局的异样处理器或自定义异样处理器,持续判断        else if (hasGlobalExceptionHandlers() && hasHandlerMappings()) {            return super.shouldApplyTo(request, handler);        }        // 否则就不能解决了        else {            return false;        }    }    // 解析异样,调用处理器解决    @Override    protected final ModelAndView doResolveException(            HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {        // 只能是HandlerMethod能力用于解决异样        HandlerMethod handlerMethod = (handler instanceof HandlerMethod ? (HandlerMethod) handler : null);        // 理论解决        return doResolveHandlerMethodException(request, response, handlerMethod, ex);    }    // 理论解决,由子类实现    protected abstract ModelAndView doResolveHandlerMethodException(            HttpServletRequest request, HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception ex);}

1.3. ExceptionHandlerExceptionResolver

ExceptionHandlerExceptionResolver
的次要性能是能够通过注解@ExceptionHandler来解决异样

1.3.1. ExceptionHandlerExceptionResolver.afterPropertiesSet

public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver        implements ApplicationContextAware, InitializingBean {    // 当属性都注入后,由上下文环境调用此办法初始化    @Override    public void afterPropertiesSet() {        // 初始化`@ControllerAdvice`注解标注的组件        initExceptionHandlerAdviceCache();        if (this.argumentResolvers == null) {            // 获取默认的参数解析器            List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();            this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);        }        if (this.returnValueHandlers == null) {            // 获取默认的响应值处理器            List<HandlerMethodReturnValueHandler> handlers = getDefaultReturnValueHandlers();            this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);        }    }    // 初始化`@ControllerAdvice`注解标注的组件    private void initExceptionHandlerAdviceCache() {        // ... 代码省略        // 获取有`@ControllerAdvice`注解的bean        List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());        // 进行遍历        for (ControllerAdviceBean adviceBean : adviceBeans) {            Class<?> beanType = adviceBean.getBeanType();            if (beanType == null) {                // 没有类型,报错            }            // @ExceptionHandler注解解析器            ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);            // 有异样解决办法            if (resolver.hasExceptionMappings()) {                // 退出全局异样处理器缓存容器                this.exceptionHandlerAdviceCache.put(adviceBean, resolver);            }            // 是ResponseBodyAdvice的子类            if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {                // 退出容器                this.responseBodyAdvice.add(adviceBean);            }        }        // ... 代码省略    }}
public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver        implements ApplicationContextAware, InitializingBean {    // 获取默认的参数解析器    protected List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {        List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();        // @SessionAttribute 解析        resolvers.add(new SessionAttributeMethodArgumentResolver());        // @RequestAttribute 解析        resolvers.add(new RequestAttributeMethodArgumentResolver());        // 从原生 ServletRequest 对象的输出流中解析申请头、申请体等        resolvers.add(new ServletRequestMethodArgumentResolver());        // 把处理器最终的数据写入到原生 ServletResponse 对象的输入流中,包含响应头、响应体等        resolvers.add(new ServletResponseMethodArgumentResolver());        // 重定向解决        resolvers.add(new RedirectAttributesMethodArgumentResolver());        // Model 解决        resolvers.add(new ModelMethodProcessor());        // ... 代码省略    }    // 获取默认的响应值处理器    protected List<HandlerMethodReturnValueHandler> getDefaultReturnValueHandlers() {        List<HandlerMethodReturnValueHandler> handlers = new ArrayList<>();        // ModelAndView 解决        handlers.add(new ModelAndViewMethodReturnValueHandler());        // Model 解决        handlers.add(new ModelMethodProcessor());        // View 解决        handlers.add(new ViewMethodReturnValueHandler());        // HttpEntity 解决        handlers.add(new HttpEntityMethodProcessor(                getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));        // 数据绑定解析        handlers.add(new ServletModelAttributeMethodProcessor(false));        // @RequestBody @ResponseBody 解析        handlers.add(new RequestResponseBodyMethodProcessor(                getMessageConverters(), this.contentNegotiationManager, this.responseBodyAdvice));        // 视图名字解决        handlers.add(new ViewNameMethodReturnValueHandler());        // Map 解决        handlers.add(new MapMethodProcessor());        // ... 代码省略        return handlers;    }}

1.3.2. ExceptionHandlerExceptionResolver.doResolveHandlerMethodException

public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExceptionResolver        implements ApplicationContextAware, InitializingBean {    // 理论解决异样    @Override    protected ModelAndView doResolveHandlerMethodException(HttpServletRequest request,            HttpServletResponse response, @Nullable HandlerMethod handlerMethod, Exception exception) {        // 获取异样解决的办法对象        ServletInvocableHandlerMethod exceptionHandlerMethod = getExceptionHandlerMethod(handlerMethod, exception);        // 如果没有,返回null        if (exceptionHandlerMethod == null) {            return null;        }        if (this.argumentResolvers != null) {            // 注入参数解析器argumentResolvers            exceptionHandlerMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);        }        if (this.returnValueHandlers != null) {            // 注入响应解决returnValueHandlers            exceptionHandlerMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);        }        ServletWebRequest webRequest = new ServletWebRequest(request, response);        // 响应容器        ModelAndViewContainer mavContainer = new ModelAndViewContainer();        ArrayList<Throwable> exceptions = new ArrayList<>();        try {            // 遍历外部的异样            Throwable exToExpose = exception;            while (exToExpose != null) {                exceptions.add(exToExpose);                Throwable cause = exToExpose.getCause();                exToExpose = (cause != exToExpose ? cause : null);            }            Object[] arguments = new Object[exceptions.size() + 1];            exceptions.toArray(arguments);            arguments[arguments.length - 1] = handlerMethod;            // 调用处理器,获取处理结果,利用响应解决returnValueHandlers            exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, arguments);        }        catch (Throwable invocationEx) {            // ... 代码省略        }        // 如果是曾经解决过了,返回空ModelAndView        if (mavContainer.isRequestHandled()) {            return new ModelAndView();        }        else {            // 获取模型对象            ModelMap model = mavContainer.getModel();            // 生成ModelAndView            ModelAndView mav = new ModelAndView(mavContainer.getViewName(), model, mavContainer.getStatus());            // ... 代码省略            // 解决重定向            if (model instanceof RedirectAttributes) {                // ... 代码省略            }            return mav;        }    }    // 获取异样解决的办法对象    protected ServletInvocableHandlerMethod getExceptionHandlerMethod(            @Nullable HandlerMethod handlerMethod, Exception exception) {        Class<?> handlerType = null;        if (handlerMethod != null) {            // 获取bean类型            handlerType = handlerMethod.getBeanType();            // 获取缓存的处理器            ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(handlerType);            // 如果没有,就生成,并缓存            if (resolver == null) {                resolver = new ExceptionHandlerMethodResolver(handlerType);                this.exceptionHandlerCache.put(handlerType, resolver);            }            // 解析解决exception的办法            Method method = resolver.resolveMethod(exception);            // 有了就返回一个封装对象            if (method != null) {                return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method);            }            // ... 代码省略        }        // 没有自定义的,就应用全局的异样处理器        for (Map.Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) {            ControllerAdviceBean advice = entry.getKey();            if (advice.isApplicableToBeanType(handlerType)) {                ExceptionHandlerMethodResolver resolver = entry.getValue();                // 解析解决exception的办法                Method method = resolver.resolveMethod(exception);                // 有了就返回一个封装对象                if (method != null) {                    return new ServletInvocableHandlerMethod(advice.resolveBean(), method);                }            }        }        return null;    }}

2. ResponseStatusExceptionResolver

ResponseStatusExceptionResolver
的次要性能是反对@ResponseStatus注解映射状态码

public class ResponseStatusExceptionResolver extends AbstractHandlerExceptionResolver implements MessageSourceAware {    // 解析异样,调用处理器解决    @Override    protected ModelAndView doResolveException(            HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {        try {            // 如果ResponseStatusException,把ResponseStatusException外部的responseHeaders设置到响应中            // 并设置响应码和响应起因            if (ex instanceof ResponseStatusException) {                return resolveResponseStatusException((ResponseStatusException) ex, request, response, handler);            }            // 不然,查看异样类的`@ResponseStatus`注解,如果有,设置响应码和响应起因            ResponseStatus status = AnnotatedElementUtils.findMergedAnnotation(ex.getClass(), ResponseStatus.class);            if (status != null) {                return resolveResponseStatus(status, request, response, handler, ex);            }            // 如果有外部异样,循环遍历解决            if (ex.getCause() instanceof Exception) {                return doResolveException(request, response, handler, (Exception) ex.getCause());            }        }        catch (Exception resolveEx) {            // ... 代码省略        }        return null;    }}

3. DefaultHandlerExceptionResolver

DefaultHandlerExceptionResolver
的次要性能是把规范 SpringMVC 异样映射状态码

public class DefaultHandlerExceptionResolver extends AbstractHandlerExceptionResolver {    // 解析异样,调用处理器解决    @Override    protected ModelAndView doResolveException(            HttpServletRequest request, HttpServletResponse response, @Nullable Object handler, Exception ex) {        try {            // 405            if (ex instanceof HttpRequestMethodNotSupportedException) {                return handleHttpRequestMethodNotSupported(                        (HttpRequestMethodNotSupportedException) ex, request, response, handler);            }            // 415            else if (ex instanceof HttpMediaTypeNotSupportedException) {                return handleHttpMediaTypeNotSupported(                        (HttpMediaTypeNotSupportedException) ex, request, response, handler);            }            // 406            else if (ex instanceof HttpMediaTypeNotAcceptableException) {                return handleHttpMediaTypeNotAcceptable(                        (HttpMediaTypeNotAcceptableException) ex, request, response, handler);            }            // 500            else if (ex instanceof MissingPathVariableException) {                return handleMissingPathVariable(                        (MissingPathVariableException) ex, request, response, handler);            }            // 400            else if (ex instanceof MissingServletRequestParameterException) {                return handleMissingServletRequestParameter(                        (MissingServletRequestParameterException) ex, request, response, handler);            }            // 400            else if (ex instanceof ServletRequestBindingException) {                return handleServletRequestBindingException(                        (ServletRequestBindingException) ex, request, response, handler);            }            // 500            else if (ex instanceof ConversionNotSupportedException) {                return handleConversionNotSupported(                        (ConversionNotSupportedException) ex, request, response, handler);            }            // 400            else if (ex instanceof TypeMismatchException) {                return handleTypeMismatch(                        (TypeMismatchException) ex, request, response, handler);            }            // 400            else if (ex instanceof HttpMessageNotReadableException) {                return handleHttpMessageNotReadable(                        (HttpMessageNotReadableException) ex, request, response, handler);            }            // 500            else if (ex instanceof HttpMessageNotWritableException) {                return handleHttpMessageNotWritable(                        (HttpMessageNotWritableException) ex, request, response, handler);            }            // 400            else if (ex instanceof MethodArgumentNotValidException) {                return handleMethodArgumentNotValidException(                        (MethodArgumentNotValidException) ex, request, response, handler);            }            // 400            else if (ex instanceof MissingServletRequestPartException) {                return handleMissingServletRequestPartException(                        (MissingServletRequestPartException) ex, request, response, handler);            }            // 400            else if (ex instanceof BindException) {                return handleBindException((BindException) ex, request, response, handler);            }            // 404            else if (ex instanceof NoHandlerFoundException) {                return handleNoHandlerFoundException(                        (NoHandlerFoundException) ex, request, response, handler);            }            // 503            else if (ex instanceof AsyncRequestTimeoutException) {                return handleAsyncRequestTimeoutException(                        (AsyncRequestTimeoutException) ex, request, response, handler);            }        }        catch (Exception handlerEx) {            // ... 代码省略        }        return null;    }}

4. DefaultRequestToViewNameTranslator

DefaultRequestToViewNameTranslator
的次要性能是把 URI 映射视图名字

public class DefaultRequestToViewNameTranslator implements RequestToViewNameTranslator {    // 依据申请获取视图名字    @Override    public String getViewName(HttpServletRequest request) {        // 获取URI的path局部        String path = ServletRequestPathUtils.getCachedPathValue(request);        // 加上前缀与后缀        return (this.prefix + transformPath(path) + this.suffix);    }    // 转换path    protected String transformPath(String lookupPath) {        String path = lookupPath;        // 去掉结尾的/        if (this.stripLeadingSlash && path.startsWith(SLASH)) {            path = path.substring(1);        }        // 去掉结尾的/        if (this.stripTrailingSlash && path.endsWith(SLASH)) {            path = path.substring(0, path.length() - 1);        }        // 去掉扩展名        if (this.stripExtension) {            path = StringUtils.stripFilenameExtension(path);        }        // 确保分隔符为/        if (!SLASH.equals(this.separator)) {            path = StringUtils.replace(path, SLASH, this.separator);        }        return path;    }}

5. InternalResourceViewResolver

InternalResourceViewResolver
的次要性能是把视图名字解析成视图对象

继承关系如下

- AbstractCachingViewResolver  - UrlBasedViewResolver    - InternalResourceViewResolver

5.1. AbstractCachingViewResolver

AbstractCachingViewResolver
的次要性能是把视图名字解析成视图对象

public abstract class AbstractCachingViewResolver extends WebApplicationObjectSupport implements ViewResolver {    // 把视图名字解析成视图对象    @Override    public View resolveViewName(String viewName, Locale locale) throws Exception {        // 如果不应用缓存,则每次都加载一次视图文件        if (!isCache()) {            return createView(viewName, locale);        }        else {            // 获取缓存键            Object cacheKey = getCacheKey(viewName, locale);            // 获取缓存            View view = this.viewAccessCache.get(cacheKey);            if (view == null) {                synchronized (this.viewCreationCache) {                    view = this.viewCreationCache.get(cacheKey);                    if (view == null) {                        // 缓存中不存在,加载创立视图对象,并退出缓存                        view = createView(viewName, locale);                        // ... 代码省略                        if (view != null) {                            this.viewAccessCache.put(cacheKey, view);                            this.viewCreationCache.put(cacheKey, view);                        }                    }                }            }            return (view != UNRESOLVED_VIEW ? view : null);        }    }    protected View createView(String viewName, Locale locale) throws Exception {        return loadView(viewName, locale);    }    // 加载视图,子类实现    protected abstract View loadView(String viewName, Locale locale) throws Exception;}

5.2. UrlBasedViewResolver

UrlBasedViewResolver
的次要性能是反对把间接视图名字映射为 url

public class UrlBasedViewResolver extends AbstractCachingViewResolver implements Ordered {    @Override    protected View createView(String viewName, Locale locale) throws Exception {        // ... 代码省略        // 以"redirect:"结尾的重定向,能够跳到其余视图        if (viewName.startsWith(REDIRECT_URL_PREFIX)) {            String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length());            RedirectView view = new RedirectView(redirectUrl,                    isRedirectContextRelative(), isRedirectHttp10Compatible());            // ... 代码省略            return view;        }        // 以"forward:"结尾的重定向,能够转发到其余视图        if (viewName.startsWith(FORWARD_URL_PREFIX)) {            String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length());            InternalResourceView view = new InternalResourceView(forwardUrl);            return view;        }        // 其余放弃父类行为        return super.createView(viewName, locale);    }}
public class UrlBasedViewResolver extends AbstractCachingViewResolver implements Ordered {    // 加载视图    @Override    protected View loadView(String viewName, Locale locale) throws Exception {        // 构建视图        AbstractUrlBasedView view = buildView(viewName);        // ... 代码省略        return view;    }    // 构建视图    protected AbstractUrlBasedView buildView(String viewName) throws Exception {        // 初始化视图类        AbstractUrlBasedView view = instantiateView();        // 设置门路        view.setUrl(getPrefix() + viewName + getSuffix());        // 设置解析数据        view.setAttributesMap(getAttributesMap());        // ... 代码省略        return view;    }}

5.3. InternalResourceViewResolver

InternalResourceViewResolver
的次要性能是反对 InternalResourceView 和 JstlView

public class InternalResourceViewResolver extends UrlBasedViewResolver {    @Override    protected AbstractUrlBasedView instantiateView() {        return (getViewClass() == InternalResourceView.class ? new InternalResourceView() :                (getViewClass() == JstlView.class ? new JstlView() : super.instantiateView()));    }}

6. 视图渲染

6.1. View

View
是所有扩大视图组件的根底接口,次要就是 render 办法

public interface View {    void render(@Nullable Map<String, ?> model, HttpServletRequest request, HttpServletResponse response)            throws Exception;}

6.2. AbstractView

AbstractView
的次要性能是反对 Spring 对视图组件以 bean 模式来治理

public abstract class AbstractView extends WebApplicationObjectSupport implements View, BeanNameAware {    // 渲染视图    @Override    public void render(@Nullable Map<String, ?> model, HttpServletRequest request,            HttpServletResponse response) throws Exception {        // 合并其余数据到模型中        Map<String, Object> mergedModel = createMergedOutputModel(model, request, response);        // 渲染合并的模型数据        renderMergedOutputModel(mergedModel, getRequestToExpose(request), response);    }    // 合并其余数据到模型中    protected Map<String, Object> createMergedOutputModel(@Nullable Map<String, ?> model,            HttpServletRequest request, HttpServletResponse response) {        // 门路变量        Map<String, Object> pathVars = (this.exposePathVariables ?                (Map<String, Object>) request.getAttribute(View.PATH_VARIABLES) : null);        // 注入的动态属性        int size = this.staticAttributes.size();        size += (model != null ? model.size() : 0);        size += (pathVars != null ? pathVars.size() : 0);        // 合并门路变量与动态属性到模型中        Map<String, Object> mergedModel = CollectionUtils.newLinkedHashMap(size);        mergedModel.putAll(this.staticAttributes);        if (pathVars != null) {            mergedModel.putAll(pathVars);        }        if (model != null) {            mergedModel.putAll(model);        }        // ... 代码省略        return mergedModel;    }    // 渲染合并的模型数据,子类实现    protected abstract void renderMergedOutputModel(            Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception;}

6.3. AbstractUrlBasedView

AbstractUrlBasedView
的次要性能是要求有一个 url 数据,其余没有什么性能

6.4. AbstractTemplateView

AbstractTemplateView
的次要性能是实现模板渲染,纯接口数据(不须要模板渲染的),间接继承 AbstractView 就能够了

public abstract class AbstractTemplateView extends AbstractUrlBasedView {    // 渲染合并的模型数据    @Override    protected final void renderMergedOutputModel(            Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {        // ... 代码省略,载入申请属性、session属性、spring宏属性到模型数据中        // 渲染合并的模型数据到模板        renderMergedTemplateModel(model, request, response);    }    // 渲染合并的模型数据到模板,子类实现    protected abstract void renderMergedTemplateModel(            Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception;}

6.5. FreeMarkerView

FreeMarkerView
的次要性能是用 FreeMarker 渲染视图

public class FreeMarkerView extends AbstractTemplateView {    // 渲染合并的模型数据到模板    @Override    protected void renderMergedTemplateModel(            Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {        doRender(model, request, response);    }    protected void doRender(Map<String, Object> model, HttpServletRequest request,            HttpServletResponse response) throws Exception {        // ... 代码省略        // 构建FreeMarker模板对象        SimpleHash fmModel = buildTemplateModel(model, request, response);        // ... 代码省略        // 获取模板文件,渲染模板到response        processTemplate(getTemplate(locale), fmModel, response);    }    // 渲染模板到response    protected void processTemplate(Template template, SimpleHash model, HttpServletResponse response)            throws IOException, TemplateException {        // 输出模板渲染后果到response writer        template.process(model, response.getWriter());    }}

6.6. MappingJackson2JsonView

MappingJackson2JsonView
的次要性能是用 jackson 来序列化输入接口数据,间接继承 AbstractView

public class MappingJackson2JsonView extends AbstractView {    // 渲染合并的模型数据    @Override    protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,            HttpServletResponse response) throws Exception {        // 字节数组输入流        ByteArrayOutputStream temporaryStream = null;        // 输入流        OutputStream stream;        // 须要更新'Content-Length'头        if (this.updateContentLength) {            // 创立一个新的长期输入流            temporaryStream = createTemporaryOutputStream();            stream = temporaryStream;        }        else {            // 不然应用response的输入流            stream = response.getOutputStream();        }        // 把一些不须要的对象过滤掉,包装成可序列化的对象        Object value = filterAndWrapModel(model, request);        // 把后果写入输入流中        writeContent(stream, value);        if (temporaryStream != null) {            // 如果有新的长期输入流,把这个新的流写入到response对象中            writeToResponse(response, temporaryStream);        }    }    // 把后果写入输入流中    protected void writeContent(OutputStream stream, Object object) throws IOException {        // 生成一个JsonGenerator        try (JsonGenerator generator = this.objectMapper.getFactory().createGenerator(stream, this.encoding)) {            // ... 代码省略            Object value = object;            Class<?> serializationView = null;            FilterProvider filters = null;            // 获取序列化视图和过滤器            if (value instanceof MappingJacksonValue) {                MappingJacksonValue container = (MappingJacksonValue) value;                value = container.getValue();                serializationView = container.getSerializationView();                filters = container.getFilters();            }            // 给writer退出序列化视图            ObjectWriter objectWriter = (serializationView != null ?                    this.objectMapper.writerWithView(serializationView) : this.objectMapper.writer());            // 给writer退出过滤器,如字段过滤            if (filters != null) {                objectWriter = objectWriter.with(filters);            }            objectWriter.writeValue(generator, value);            // ... 代码省略            // 刷新数据            generator.flush();        }    }}

后续

更多博客,查看 https://github.com/senntyou/blogs

作者:深予之 (@senntyou)

版权申明:自在转载-非商用-非衍生-放弃署名(创意共享 3.0 许可证)