欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

使用自定義參數(shù)解析器同一個參數(shù)支持多種Content-Type

 更新時間:2021年08月18日 09:53:43   作者:DDF_YiChen  
這篇文章主要介紹了使用自定義參數(shù)解析器同一個參數(shù)支持多種Content-Type的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

一堆廢話

事出有因, 原先上線的接口現(xiàn)在被要求用Java重寫,按照原暴露出去的文檔然后毫無疑問的,按照Java的慣例,

一定是@RequestBody然后去接收application/json;charset=utf-8,然后一通參數(shù)接收處理邏輯。

結(jié)果測試都通過了,上線的時候,剛把原接口切到新接口上,日志就狂飆

application/x-www-form-urlencoded;charset=utf-8 NOT SUPPORT

What?然后就一通問號臉。趕緊把接口切回到老接口,然后跑去問PHP的同事,什么情況,原對接參數(shù)不是json嗎?

然后才明白,草,原來要同時支持application/json;charset=utf-8和application/x-www-form-urlencoded;charset=utf-8

PHP咱是不懂的,但是Java對這個需求的原生支持卻不是很好,印象中沒有現(xiàn)成的。

因為一般我們定義對象接收參數(shù),如果使用了@RequestBody接收,那么傳參一定要使用post+一個對應(yīng)的參數(shù)解析器一個可讀的流,按照現(xiàn)在的情況即application/json;charset=utf-8。

要么是直接一個對象接收,不要加任何注解,這個時候?qū)?yīng)的Content-Type是application/x-www-form-urlencoded;charset=utf-8則參數(shù)可正常解析。

但是這兩種情況是矛盾的,如果一個加了@RequestBody的參數(shù)對應(yīng)的Content-Type是application/x-www-form-urlencoded;charset=utf-8, 則最終無法解析。反過來如果一個未加@RequestBody的參數(shù)對應(yīng)的Content-Type是application/json;charset=utf-8則也無法解析。

那么現(xiàn)在就只能來看一下如何定義一個自定義的參數(shù)解析器來完成這個需求了。但是這個自定義的參數(shù)解析器還有點不太一樣,因為數(shù)據(jù)格式本身不是我們自定義的,本身就存在對應(yīng)標準的解析器。只是SpringMVC在根據(jù)參數(shù)去找對應(yīng)解析器的時候沒有對應(yīng)起來。我們現(xiàn)在只要讓自己的解析器能夠讓這個參數(shù)轉(zhuǎn)發(fā)到對應(yīng)可以解析的參數(shù)解析器上就可以了。

探究Springmvc參數(shù)解析器工作流程

現(xiàn)在就要不怕麻煩的還看一下原來的參數(shù)解析器是如何工作的,畢竟不知道它怎么寫的我也不知道怎么抄。

SpringMVC項目,二話不說,直接找到org.springframework.web.servlet.DispatcherServlet#doDispatch這個方法,看整個處理器的流程,這里直接簡化找到最終映射到方法后的執(zhí)行

// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

方法跳轉(zhuǎn)流程如下

public abstract class AbstractHandlerMethodAdapter extends WebContentGenerator implements HandlerAdapter, Ordered {
 @Override
 @Nullable
 public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
   throws Exception {
  return handleInternal(request, response, (HandlerMethod) handler);
 }
}

我再跳

org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#handleInternal
public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
  implements BeanFactoryAware, InitializingBean {
 /**
  * 參數(shù)解析器列表
  */
 @Nullable
 private HandlerMethodArgumentResolverComposite argumentResolvers;
 
 @Override
 protected ModelAndView handleInternal(HttpServletRequest request,
   HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
  ModelAndView mav;
  checkRequest(request);
  // 這里刪除了大量相關(guān)判斷方法,只關(guān)注實際跳轉(zhuǎn)執(zhí)行方法
  // No synchronization on session demanded at all...
  mav = invokeHandlerMethod(request, response, handlerMethod); 
 }
 
 /**
  * 上面跳到了這里
  */
 @Nullable
 protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
   HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
  // 這里又刪除了大量的代碼
  ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
  // 將本類自己的參數(shù)解析器列表賦值給ServletInvocableHandlerMethod 
  if (this.argumentResolvers != null) {
   invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
  }
  if (this.returnValueHandlers != null) {
   invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
  }
  invocableMethod.setDataBinderFactory(binderFactory);
  invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
  // 帶著使命繼續(xù)往下執(zhí)行
  invocableMethod.invokeAndHandle(webRequest, mavContainer);
 }
}

接著跳到了

org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod#invokeAndHandle
public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
 public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
   Object... providedArgs) throws Exception {
  Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
  // 再刪除無關(guān)代碼
 }
}

這里總算看到了一些關(guān)鍵信息了

org.springframework.web.method.support.InvocableHandlerMethod#invokeForRequest
public class InvocableHandlerMethod extends HandlerMethod {
 @Nullable
 public Object invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
   Object... providedArgs) throws Exception {
  // 這里就是解析參數(shù)
  Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
  if (logger.isTraceEnabled()) {
   logger.trace("Arguments: " + Arrays.toString(args));
  }
  return doInvoke(args);
 }
 
 /**
  * 上面方法跳到了這里
  */
 protected Object[] getMethodArgumentValues(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer,
   Object... providedArgs) throws Exception {
  // 這里就是獲取入?yún)⒌膮?shù)類型,如單個字符串的每個參數(shù),或者是某個對象參數(shù),甚至是HttpServletRequest
  MethodParameter[] parameters = getMethodParameters();
  if (ObjectUtils.isEmpty(parameters)) {
   return EMPTY_ARGS;
  }
  
  Object[] args = new Object[parameters.length];
  // 下面就是遍歷每個參數(shù)類型,然后挨個解析
  for (int i = 0; i < parameters.length; i++) {
   MethodParameter parameter = parameters[i];
   parameter.initParameterNameDiscovery(this.parameterNameDiscoverer);
   args[i] = findProvidedArgument(parameter, providedArgs);
   if (args[i] != null) {
    continue;
   }
   // org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#supportsParameter
   // 后面就貼出了這個方法的內(nèi)部,就是遍歷所有的參數(shù)解析器判斷是否能夠解析當前參數(shù)
   if (!this.resolvers.supportsParameter(parameter)) {
    throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
   }
   try {
       // 獲取參數(shù)解析器,解析當前參數(shù)
    args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
   }
   catch (Exception ex) {
    // Leave stack trace for later, exception may actually be resolved and handled...
    if (logger.isDebugEnabled()) {
     String exMsg = ex.getMessage();
     if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) {
      logger.debug(formatArgumentError(parameter, exMsg));
     }
    }
    throw ex;
   }
  }
  return args;
 }
}

上面關(guān)于找到參數(shù)解析器的關(guān)鍵代碼

org.springframework.web.method.support.HandlerMethodArgumentResolverComposite
public class HandlerMethodArgumentResolverComposite implements HandlerMethodArgumentResolver {
  private final List<HandlerMethodArgumentResolver> argumentResolvers = new LinkedList<>();
 private final Map<MethodParameter, HandlerMethodArgumentResolver> argumentResolverCache =
   new ConcurrentHashMap<>(256);
 
 /**
  * 判斷參數(shù)是否能夠找到對應(yīng)的參數(shù)解析器
  */
 @Override
 public boolean supportsParameter(MethodParameter parameter) {
  return getArgumentResolver(parameter) != null;
 }
 
 @Nullable
 private HandlerMethodArgumentResolver getArgumentResolver(MethodParameter parameter) {
  // 這里指向一個本地緩存,如果一個參數(shù)類型可以被某個參數(shù)解析器解析,則緩存下次無須遍歷
  HandlerMethodArgumentResolver result = this.argumentResolverCache.get(parameter);
  if (result == null) {
      // 遍歷所有的參數(shù)解析器,判斷是否支持當前參數(shù)類型
   for (HandlerMethodArgumentResolver resolver : this.argumentResolvers) {
    if (resolver.supportsParameter(parameter)) {
     result = resolver;
     // 如果支持則放入本地緩存,下次直接從緩存中取
     this.argumentResolverCache.put(parameter, result);
     break;
    }
   }
  }
  return result;
 }
 
 @Override
 @Nullable
 public Object resolveArgument(MethodParameter parameter, @Nullable ModelAndViewContainer mavContainer,
   NativeWebRequest webRequest, @Nullable WebDataBinderFactory binderFactory) throws Exception {
  // 獲取該參數(shù)類型對應(yīng)的參數(shù)解析器
  HandlerMethodArgumentResolver resolver = getArgumentResolver(parameter);
  if (resolver == null) {
   throw new IllegalArgumentException("Unsupported parameter type [" +
     parameter.getParameterType().getName() + "]. supportsParameter should be called first.");
  }
  // 解析參數(shù)
  return resolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
 } 
}

通過對

org.springframework.web.method.support.HandlerMethodArgumentResolverComposite#getArgumentResolver

的調(diào)試, 我們貼出幾張圖來說明系統(tǒng)中目前所有的參數(shù)解析器,以及我們目前需要的用來解析@RequestBody和application/x-www-form-urlencoded對應(yīng)的參數(shù)解析器

application/x-www-form-urlencoded對應(yīng)的解析器為ServletModelAttributeMethodProcessor
@RequestBody application/json對應(yīng)的解析器為RequestResponseBodyMethodProcessor
public class RequestResponseBodyMethodProcessor extends AbstractMessageConverterMethodProcessor {
 @Override
 public boolean supportsParameter(MethodParameter parameter) {
     // 可以看到必須要有RequestBody這個注解,該參數(shù)解析器才會工作
  return parameter.hasParameterAnnotation(RequestBody.class);
 }
}

順便說下為什么我們在controller方法入?yún)⒌臅r候?qū)慔ttpServletRequest和HttpServletResponse也能夠入?yún)⑦M來,就是因為有對應(yīng)的參數(shù)解析器,這里也給找出來了

org.springframework.web.servlet.mvc.method.annotation.ServletRequestMethodArgumentResolver
org.springframework.web.servlet.mvc.method.annotation.ServletResponseMethodArgumentResolver

不想看廢話的可以直接進結(jié)果

定義一個注解用于標注在參數(shù)上,用以標識這個參數(shù)希望用我們的參數(shù)解析器進行解析

import java.lang.annotation.*;
/**
 * <p>標識參數(shù)可以被多個參數(shù)解析器嘗試進行參數(shù)解析</p >
 *
 * 同一個參數(shù)支持application/json和application/x-www-form-urlencoded
 *
 * @see com.company.content.risk.order.common.handle.MultiArgumentResolverMethodProcessor
 * @author Snowball
 * @version 1.0
 * @date 2020/08/31 18:57
 */
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MultiArgumentResolver {
}

實現(xiàn)一個自定義參數(shù)解析器,要實現(xiàn)接口org.springframework.web.method.support.HandlerMethodArgumentResolver。在解析方法里我們?nèi)ヅ袛喈斍翱蛻舳藗魅氲腃ontent-Type, 如果是application/json則將參數(shù)解析交給RequestResponseBodyMethodProcessor, 如果是application/x-www-form-urlencoded, 則將參數(shù)解析交給ServletModelAttributeMethodProcessor。

HandlerMethodArgumentResolver接口要實現(xiàn)兩個方法

  • supportsParameter 判斷當前解析器是否支持入?yún)ο?/li>
  • resolveArgument 解析邏輯
import com.company.content.risk.order.common.annotation.MultiArgumentResolver;
import com.google.common.collect.ImmutableList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.web.HttpMediaTypeNotSupportedException;
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.HandlerMethodArgumentResolverComposite;
import org.springframework.web.method.support.ModelAndViewContainer;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestResponseBodyMethodProcessor;
import org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 自定義參數(shù)解析器用以支持同一個參數(shù)支持application/json和application/x-www-form-urlencoded解析
 *
 * @see MultiArgumentResolver
 * @author Snowball
 * @version 1.0
 * @date 2020/08/31 19:00
 */
public class MultiArgumentResolverMethodProcessor implements HandlerMethodArgumentResolver  {
    @Autowired
    private RequestMappingHandlerAdapter requestMappingHandlerAdapter;
    private static final String CONTENT_TYPE_JSON = "application/json";
    private static final String CONTENT_TYPE_FORM_URLENCODED = "application/x-www-form-urlencoded";
    /**
     * 支持的content_type
     */
    private static final ImmutableList<String> SUPPORT_CONTENT_TYPE_LIST = ImmutableList.of(CONTENT_TYPE_JSON, CONTENT_TYPE_FORM_URLENCODED);
    /**
     * 參考這個寫法, 同一個類型的參數(shù)解析后緩存對應(yīng)的參數(shù)解析器,不過這里的key改為了Content-Type
     * @see HandlerMethodArgumentResolverComposite#argumentResolverCache
     */
    private final Map<String, HandlerMethodArgumentResolver> argumentResolverCache =
            new ConcurrentHashMap<>(8);
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.getParameter().isAnnotationPresent(MultiArgumentResolver.class);
    }
    /**
     * 解析參數(shù)
     */
    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        String contentType = webRequest.getHeader("Content-Type");
        isSupport(contentType);
        List<HandlerMethodArgumentResolver> argumentResolvers = requestMappingHandlerAdapter.getArgumentResolvers();
        HandlerMethodArgumentResolver handlerMethodArgumentResolver = argumentResolverCache.get(contentType);
        if (handlerMethodArgumentResolver != null) {
            return handlerMethodArgumentResolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
        }
        for (HandlerMethodArgumentResolver argumentResolver : argumentResolvers) {
            if (isJson(contentType) && argumentResolver instanceof RequestResponseBodyMethodProcessor) {
                argumentResolverCache.put(contentType, argumentResolver);
                return argumentResolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
            } else if (isFormUrlEncoded(contentType) && argumentResolver instanceof ServletModelAttributeMethodProcessor) {
                argumentResolverCache.put(contentType, argumentResolver);
                return argumentResolver.resolveArgument(parameter, mavContainer, webRequest, binderFactory);
            }
        }
        return null;
    }
    private boolean isJson(String contentType) {
        return contentType.contains(CONTENT_TYPE_JSON);
    }
    private boolean isFormUrlEncoded(String contentType) {
        return contentType.contains(CONTENT_TYPE_FORM_URLENCODED);
    }
    /**
     * 判斷當前參數(shù)解析器是否支持解析當前的Content-Type
     * @param contentType
     * @return
     * @throws HttpMediaTypeNotSupportedException
     */
    private boolean isSupport(String contentType) throws HttpMediaTypeNotSupportedException {
        if (contentType == null) {
            throw new HttpMediaTypeNotSupportedException("contentType不能為空");
        }
        boolean isMatch = false;
        for (String item : SUPPORT_CONTENT_TYPE_LIST) {
            if (contentType.contains(item)) {
                isMatch = true;
                break;
            }
        }
        if (!isMatch) {
            throw new HttpMediaTypeNotSupportedException("支持Content-Type" + SUPPORT_CONTENT_TYPE_LIST.toString());
        }
        return true;
    }

將參數(shù)解析器注冊成bean,添加到系統(tǒng)參數(shù)解析器列表即可

import com.company.content.risk.order.common.handle.MultiArgumentResolverMethodProcessor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.List;
/**
 * <p>web核心配置</p >
 *
 * @author Snowball
 * @version 1.0
 * @date 2020/08/31 18:57
 */
@Configuration
@Order
public class CoreWebConfig implements WebMvcConfigurer {
    /**
     * 注冊自定義參數(shù)解析器
     * @return
     */
    @Bean
    public MultiArgumentResolverMethodProcessor multiArgumentResolverMethodProcessor() {
        return new MultiArgumentResolverMethodProcessor();
    }
    /**
     * 添加自定義參數(shù)解析器
     * @param resolvers
     */
    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
        resolvers.add(0, multiArgumentResolverMethodProcessor());
    }
}

使用,將@MultiArgumentResolver標識在controller方法的某個入?yún)ο蠹纯?/p>

@PostMapping(value = "text/submit")
public OutApiResponse<OutTextResponseBody> submitText(@MultiArgumentResolver OutTextRequest outTextRequest) {
}

補充

在上面自定義參數(shù)解析器的類中,注入了一個bean,類為RequestMappingHandlerAdapter, 目的是為了從這個類中獲取到目前系統(tǒng)中已有的參數(shù)解析器列表。那么如何知道這個類里面包含了哪些參數(shù)解析器呢?摘錄相關(guān)代碼如下。這個類實現(xiàn)了接口InitializingBean,在bean初始化完成后調(diào)用afterPropertiesSet,然后在里面判斷加入了默認的參數(shù)解析器列表

public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter
		implements BeanFactoryAware, InitializingBean {
	@Nullable
	private HandlerMethodArgumentResolverComposite argumentResolvers;
	
	@Override
	public void afterPropertiesSet() {
		// Do this first, it may add ResponseBody advice beans
		initControllerAdviceCache();
		if (this.argumentResolvers == null) {
			List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers();
			this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);
		}
	}
	private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
		List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>();
		// Annotation-based argument resolution
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
		resolvers.add(new RequestParamMapMethodArgumentResolver());
		resolvers.add(new PathVariableMethodArgumentResolver());
		resolvers.add(new PathVariableMapMethodArgumentResolver());
		resolvers.add(new MatrixVariableMethodArgumentResolver());
		resolvers.add(new MatrixVariableMapMethodArgumentResolver());
		resolvers.add(new ServletModelAttributeMethodProcessor(false));
		resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
		resolvers.add(new RequestHeaderMapMethodArgumentResolver());
		resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
		resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
		resolvers.add(new SessionAttributeMethodArgumentResolver());
		resolvers.add(new RequestAttributeMethodArgumentResolver());
		// Type-based argument resolution
		resolvers.add(new ServletRequestMethodArgumentResolver());
		resolvers.add(new ServletResponseMethodArgumentResolver());
		resolvers.add(new HttpEntityMethodProcessor(getMessageConverters(), this.requestResponseBodyAdvice));
		resolvers.add(new RedirectAttributesMethodArgumentResolver());
		resolvers.add(new ModelMethodProcessor());
		resolvers.add(new MapMethodProcessor());
		resolvers.add(new ErrorsMethodArgumentResolver());
		resolvers.add(new SessionStatusMethodArgumentResolver());
		resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
		// Custom arguments
		if (getCustomArgumentResolvers() != null) {
			resolvers.addAll(getCustomArgumentResolvers());
		}
		// Catch-all
		resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
		resolvers.add(new ServletModelAttributeMethodProcessor(true));
		return resolvers;
	}
}

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java的布爾類型基本介紹

    Java的布爾類型基本介紹

    這篇文章主要介紹了Java的布爾類型,是Java入門學習中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-10-10
  • SpringBoot3集成和使用Jasypt的代碼詳解

    SpringBoot3集成和使用Jasypt的代碼詳解

    隨著信息安全的日益受到重視,加密敏感數(shù)據(jù)在應(yīng)用程序中變得越來越重要,Jasypt作為一個簡化Java應(yīng)用程序中數(shù)據(jù)加密的工具,為開發(fā)者提供了一種便捷而靈活的加密解決方案,本文將深入解析Jasypt的工作原理,需要的朋友可以參考下
    2024-01-01
  • Ubuntu 15下安裝JDK1.8教程

    Ubuntu 15下安裝JDK1.8教程

    這篇文章主要為大家詳細介紹了Ubuntu 15下JDK1.8安裝教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-12-12
  • Springboot es包版本異常解決方案

    Springboot es包版本異常解決方案

    這篇文章主要介紹了springboot 項目依賴 es包版本異常,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • Java實現(xiàn)簡單版貪吃蛇游戲

    Java實現(xiàn)簡單版貪吃蛇游戲

    這篇文章主要為大家詳細介紹了Java實現(xiàn)簡單版貪吃蛇游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • SpringBoot全局處理統(tǒng)一返回類型方式

    SpringBoot全局處理統(tǒng)一返回類型方式

    這篇文章主要介紹了SpringBoot全局處理統(tǒng)一返回類型方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Nacos配置的多文件加載與共享配置方式

    Nacos配置的多文件加載與共享配置方式

    這篇文章主要介紹了Nacos配置的多文件加載與共享配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 探討Java中函數(shù)是值傳遞還是引用傳遞問題

    探討Java中函數(shù)是值傳遞還是引用傳遞問題

    這篇文章主要介紹了探討Java中函數(shù)是值傳遞還是引用傳遞問題,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02
  • Java網(wǎng)絡(luò)IO模型詳解(BIO、NIO、AIO)

    Java網(wǎng)絡(luò)IO模型詳解(BIO、NIO、AIO)

    Java支持BIO、NIO和AIO三種網(wǎng)絡(luò)IO模型,BIO是同步阻塞模型,適用于連接數(shù)較少的場景,NIO是同步非阻塞模型,適用于處理多個連接,支持自JDK1.4起,AIO是異步非阻塞模型,適用于異步操作多的場景,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-10-10
  • Java讀取properties文件之中文亂碼問題及解決

    Java讀取properties文件之中文亂碼問題及解決

    這篇文章主要介紹了Java讀取properties文件之中文亂碼問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12

最新評論