SpringMvc返回Json调试

spring-web-5.0.6.RELEASE.jar!/org/springframework/web/method/support/HandlerMethodReturnValueHandlerComposite.class

public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws Exception {
        HandlerMethodReturnValueHandler handler = this.selectHandler(returnValue, returnType);
        if (handler == null) {
            throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
        } else {
            handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
        }
    }

spring-webmvc-5.0.6.RELEASE.jar!/org/springframework/web/servlet/mvc/method/annotation/RequestResponseBodyMethodProcessor.class

    public void handleReturnValue(@Nullable Object returnValue, MethodParameter returnType, ModelAndViewContainer mavContainer, NativeWebRequest webRequest) throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
        mavContainer.setRequestHandled(true);
        ServletServerHttpRequest inputMessage = this.createInputMessage(webRequest);
        ServletServerHttpResponse outputMessage = this.createOutputMessage(webRequest);
        this.writeWithMessageConverters(returnValue, returnType, inputMessage, outputMessage);
    }

spring-webmvc-5.0.6.RELEASE.jar!/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.class

protected <T> void writeWithMessageConverters(@Nullable T value, MethodParameter returnType, ServletServerHttpRequest inputMessage, ServletServerHttpResponse outputMessage) throws IOException, HttpMediaTypeNotAcceptableException, HttpMessageNotWritableException {
        Object outputValue;
        Class valueType;
        Object declaredType;
        if (value instanceof CharSequence) {
            outputValue = value.toString();
            valueType = String.class;
            declaredType = String.class;
        } else {
            outputValue = value;
            valueType = this.getReturnValueType(value, returnType);
            declaredType = this.getGenericType(returnType);
        }

        if (this.isResourceType(value, returnType)) {
            outputMessage.getHeaders().set("Accept-Ranges", "bytes");
            if (value != null && inputMessage.getHeaders().getFirst("Range") != null) {
                Resource resource = (Resource)value;

                try {
                    List<HttpRange> httpRanges = inputMessage.getHeaders().getRange();
                    outputMessage.getServletResponse().setStatus(HttpStatus.PARTIAL_CONTENT.value());
                    outputValue = HttpRange.toResourceRegions(httpRanges, resource);
                    valueType = outputValue.getClass();
                    declaredType = RESOURCE_REGION_LIST_TYPE;
                } catch (IllegalArgumentException var17) {
                    outputMessage.getHeaders().set("Content-Range", "bytes */" + resource.contentLength());
                    outputMessage.getServletResponse().setStatus(HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE.value());
                }
            }
        }

        MediaType contentType = outputMessage.getHeaders().getContentType();
        Object mediaTypesToUse;
        if (contentType != null && contentType.isConcrete()) {
            mediaTypesToUse = Collections.singletonList(contentType);
        } else {
            HttpServletRequest request = inputMessage.getServletRequest();
            List<MediaType> requestedMediaTypes = this.getAcceptableMediaTypes(request);
            List<MediaType> producibleMediaTypes = this.getProducibleMediaTypes(request, valueType, (Type)declaredType);
            if (outputValue != null && producibleMediaTypes.isEmpty()) {
                throw new HttpMessageNotWritableException("No converter found for return value of type: " + valueType);
            }

            mediaTypesToUse = new ArrayList();
            Iterator var13 = requestedMediaTypes.iterator();

            while(var13.hasNext()) {
                MediaType requestedType = (MediaType)var13.next();
                Iterator var15 = producibleMediaTypes.iterator();

                while(var15.hasNext()) {
                    MediaType producibleType = (MediaType)var15.next();
                    if (requestedType.isCompatibleWith(producibleType)) {
                        ((List)mediaTypesToUse).add(this.getMostSpecificMediaType(requestedType, producibleType));
                    }
                }
            }

            if (((List)mediaTypesToUse).isEmpty()) {
                if (outputValue != null) {
                    throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
                }

                return;
            }

            MediaType.sortBySpecificityAndQuality((List)mediaTypesToUse);
        }

        MediaType selectedMediaType = null;
        Iterator var21 = ((List)mediaTypesToUse).iterator();

        while(var21.hasNext()) {
            MediaType mediaType = (MediaType)var21.next();
            if (mediaType.isConcrete()) {
                selectedMediaType = mediaType;
                break;
            }

            if (mediaType.equals(MediaType.ALL) || mediaType.equals(MEDIA_TYPE_APPLICATION)) {
                selectedMediaType = MediaType.APPLICATION_OCTET_STREAM;
                break;
            }
        }

        HttpMessageConverter converter;
        GenericHttpMessageConverter genericConverter;
        label138: {
            if (selectedMediaType != null) {
                selectedMediaType = selectedMediaType.removeQualityValue();
                var21 = this.messageConverters.iterator();

                while(var21.hasNext()) {
                    converter = (HttpMessageConverter)var21.next();
                    genericConverter = converter instanceof GenericHttpMessageConverter ? (GenericHttpMessageConverter)converter : null;
                    if (genericConverter != null) {
                        if (((GenericHttpMessageConverter)converter).canWrite((Type)declaredType, valueType, selectedMediaType)) {
                            break label138;
                        }
                    } else if (converter.canWrite(valueType, selectedMediaType)) {
                        break label138;
                    }
                }
            }

            if (outputValue != null) {
                throw new HttpMediaTypeNotAcceptableException(this.allSupportedMediaTypes);
            }

            return;
        }

        outputValue = this.getAdvice().beforeBodyWrite(outputValue, returnType, selectedMediaType, converter.getClass(), inputMessage, outputMessage);
        if (outputValue != null) {
            this.addContentDispositionHeader(inputMessage, outputMessage);
            if (genericConverter != null) {
                genericConverter.write(outputValue, (Type)declaredType, selectedMediaType, outputMessage);
            } else {
                converter.write(outputValue, selectedMediaType, outputMessage);
            }

            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Written [" + outputValue + "] as \"" + selectedMediaType + "\" using [" + converter + "]");
            }
        }

    }

序列化对象。
jackson-databind-2.9.5-sources.jar!/com/fasterxml/jackson/databind/ser/BeanSerializer.java

public final void serialize(Object bean, JsonGenerator gen, SerializerProvider provider)
        throws IOException
    {
        if (_objectIdWriter != null) {
            gen.setCurrentValue(bean); // [databind#631]
            _serializeWithObjectId(bean, gen, provider, true);
            return;
        }
        gen.writeStartObject(bean);
        if (_propertyFilterId != null) {
            serializeFieldsFiltered(bean, gen, provider);
        } else {
            serializeFields(bean, gen, provider);
        }
        gen.writeEndObject();
    }

序列化对象的字段。
jackson-databind-2.9.5-sources.jar!/com/fasterxml/jackson/databind/ser/std/BeanSerializerBase.java

protected void serializeFields(Object bean, JsonGenerator gen, SerializerProvider provider)
        throws IOException
    {
        final BeanPropertyWriter[] props;
        if (_filteredProps != null && provider.getActiveView() != null) {
            props = _filteredProps;
        } else {
            props = _props;
        }
        int i = 0;
        try {
            for (final int len = props.length; i < len; ++i) {
                BeanPropertyWriter prop = props[i];
                if (prop != null) { // can have nulls in filtered list
                    prop.serializeAsField(bean, gen, provider);
                }
            }
            if (_anyGetterWriter != null) {
                _anyGetterWriter.getAndSerialize(bean, gen, provider);
            }
        } catch (Exception e) {
            String name = (i == props.length) ? "[anySetter]" : props[i].getName();
            wrapAndThrow(provider, e, bean, name);
        } catch (StackOverflowError e) {
            // 04-Sep-2009, tatu: Dealing with this is tricky, since we don't have many
            //   stack frames to spare... just one or two; can't make many calls.

            // 10-Dec-2015, tatu: and due to above, avoid "from" method, call ctor directly:
            //JsonMappingException mapE = JsonMappingException.from(gen, "Infinite recursion (StackOverflowError)", e);
            JsonMappingException mapE = new JsonMappingException(gen, "Infinite recursion (StackOverflowError)", e);

             String name = (i == props.length) ? "[anySetter]" : props[i].getName();
            mapE.prependPath(new JsonMappingException.Reference(bean, name));
            throw mapE;
        }
    }

序列化某一个字段
jackson-databind-2.9.5-sources.jar!/com/fasterxml/jackson/databind/ser/BeanPropertyWriter.java

public void serializeAsField(Object bean, JsonGenerator gen,
            SerializerProvider prov) throws Exception {
        // inlined 'get()'
        final Object value = (_accessorMethod == null) ? _field.get(bean)
                : _accessorMethod.invoke(bean, (Object[]) null);

        // Null handling is bit different, check that first
        if (value == null) {
            if (_nullSerializer != null) {
                gen.writeFieldName(_name);
                _nullSerializer.serialize(null, gen, prov);
            }
            return;
        }
        // then find serializer to use
        JsonSerializer<Object> ser = _serializer;
        if (ser == null) {
            Class<?> cls = value.getClass();
            PropertySerializerMap m = _dynamicSerializers;
            ser = m.serializerFor(cls);
            if (ser == null) {
                ser = _findAndAddDynamic(m, cls, prov);
            }
        }
        // and then see if we must suppress certain values (default, empty)
        if (_suppressableValue != null) {
            if (MARKER_FOR_EMPTY == _suppressableValue) {
                if (ser.isEmpty(prov, value)) {
                    return;
                }
            } else if (_suppressableValue.equals(value)) {
                return;
            }
        }
        // For non-nulls: simple check for direct cycles
        if (value == bean) {
            // three choices: exception; handled by call; or pass-through
            if (_handleSelfReference(bean, gen, prov, ser)) {
                return;
            }
        }
        gen.writeFieldName(_name);
        if (_typeSerializer == null) {
            ser.serialize(value, gen, prov);
        } else {
            ser.serializeWithType(value, gen, prov, _typeSerializer);
        }
    }
posted @ 2018-05-20 19:33  NewSea  阅读(411)  评论(0编辑  收藏  举报