All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.easycode8.fastapi.core.ServiceMethodArgumentResolver Maven / Gradle / Ivy

The newest version!
package com.easycode8.fastapi.core;


import com.easycode8.fastapi.core.customizer.MethodChooseCustomizer;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.GenericTypeResolver;
import org.springframework.core.MethodParameter;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;

import static org.springframework.web.context.request.RequestAttributes.SCOPE_REQUEST;

public class ServiceMethodArgumentResolver implements HandlerMethodArgumentResolver {
    private static final String SERVICE_ARGS = "service_args";

    private final ObjectMapper innnerObjectMapper = new ObjectMapper();
    //使用springboot上下文的的jackson处理器
    private final ObjectMapper objectMapper;

    private final MethodChooseCustomizer methodChooseCustomizer;

    public ServiceMethodArgumentResolver(ObjectMapper objectMapper, MethodChooseCustomizer methodChooseCustomizer) {
        this.objectMapper = objectMapper;
        this.methodChooseCustomizer = methodChooseCustomizer;
    }

    @Override
    public boolean supportsParameter(MethodParameter parameter) {
//        return parameter.getMethod().getDeclaringClass().getDeclaredAnnotation(Service.class) != null;
        return methodChooseCustomizer.isHandler(parameter.getDeclaringClass()) && methodChooseCustomizer.supportsMethodType(parameter.getMethod());
    }

    /**
     * 参数解析
     * 第一次将请求内容解析成map, 并保存到request中,下个参数解析直接从map里面取
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws IOException {
        Map serviceArgs = (Map) webRequest.getAttribute(SERVICE_ARGS, SCOPE_REQUEST);
        if (serviceArgs == null) {
            HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
            serviceArgs = innnerObjectMapper.readValue(servletRequest.getInputStream(), ModelMap.class);
            webRequest.setAttribute(SERVICE_ARGS, serviceArgs, SCOPE_REQUEST);
        }
        Object parameterValueRaw = serviceArgs.get(parameter.getParameterName());
        if (parameterValueRaw == null) {
            return null;
        }
        // 原生内部数据转化使用默认的序列化策略, 保证下面的readValue走springboot框架objectMapper反序列化之前,数据未被修改
        String parameterValueStr = innnerObjectMapper.writeValueAsString(parameterValueRaw);
        JavaType javaType = objectMapper.getTypeFactory().constructType(GenericTypeResolver.resolveType(parameter.getGenericParameterType(), parameter.getContainingClass()));
        return objectMapper.readValue(parameterValueStr, javaType);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy