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

解決Spring?MVC中文亂碼的編碼配置

 更新時間:2023年10月26日 09:00:39   作者:福  
這篇文章主要為大家介紹了解決SpringMVC中文亂碼的編碼配置示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

SpringMVC配置編碼方式

SpringMVC的中文亂碼問題其實已經不是什么問題了,無非就是配置編碼方式->解決問題。

但是由于SpringMVC可以通過:xml方式配置、Servlet3.0方式配置,以及是否使用@EnableWebMvc等,不同配置方式下,解決中文亂碼問題的方案有所不同。

xml配置的方式

xml配置方式的解決方案最簡單:

<filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>utf-8</param-value>
    </init-param>
    <init-param>
      <param-name>forceRequestEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
    <init-param>
      <param-name>forceResponseEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

在web.xml文件中加編碼過濾器,并強制過濾器對Request和Response都生效,可以解決request請求、以及response返回參數(shù)中的中文亂碼問題。

但是返回體,也就是response body中的中文亂碼問題,以上過濾器方案無法解決。

Response body中的中文亂碼問題需要在spring MVC中增加以下配置:

<mvc:annotation-driven >
        <!--設置響應輸出字符集-->
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/html;charset=utf-8</value>
                    </list>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

前面一篇文章[Spring MVC 五:DispatcherServlet初始化之 mvc:annotation-driven] 分析過<mvc:annotation-driven />標簽的解析過程,該標簽在創(chuàng)建RequestMappingHandlerAdapter的過程中,會讀取到xml文件中messageConverters的定義并設置到RequestMappingHandlerAdapter對象的messageConverters屬性中并最終在DispatcherServlet處理請求的過程中生效。

Servlet3.0配置

Servlet3.0的配置方式,是指通過WebApplicationInitializer接口完成SpringMVC配置的方式。

可以通過接口方法getServletFilters增加編碼過濾器:

public class MvcInitializer
        extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
//        return null;
        return new Class[] {RootConfiguration.class};
    }
    @Override
    protected Class<?>[] getServletConfigClasses() {
//        return null;
        return new Class[] {MvcConfiguration.class,CommonConfiguration.class};
    }
    @Override
    protected String[] getServletMappings() {
        return new String[] {"/"};
    }
    @Override
    protected Filter[] getServletFilters() {
//        ShallowEtagHeaderFilter shallowEtagHeaderFilter = new ShallowEtagHeaderFilter();
//        shallowEtagHeaderFilter.setWriteWeakETag(true);
        CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
        characterEncodingFilter.setEncoding("utf-8");
        characterEncodingFilter.setForceEncoding(true);
        return new Filter[]{characterEncodingFilter};
    }
}

以上方式增加過濾器后,可以解決request和response請求及返回參數(shù)中的中文編碼問題。

但是無法解決response body的中文亂碼問題。

由于WebApplicationInitializer接口并沒有提供任何關于messageConverters的接口,看了很多遍源碼也并沒有找到可以配置的地方,網上也沒有找到相關解決方案......所以解決這個問題還是費了很多周折。

由于我們已經知道,response body的中文亂碼問題最終是通過RequestMappingHandlerAdapter對象的messageConverters解決的,所以還是想通過定制化RequestMappingHandlerAdapter的初始化過程、設置其messageConverters的方式解決問題。

如果沒有定制化處理的話,DispatcherServlet在初始化的過程中是在initStrategies方法中創(chuàng)建DispatcherServlet.properties文件中默認的RequestMappingHandlerAdapter,是通過反射機制直接new出來的,最終會調用到RequestMappingHandlerAdapter的默認構造器:

public RequestMappingHandlerAdapter() {
        this.messageConverters = new ArrayList<>(4);
        this.messageConverters.add(new ByteArrayHttpMessageConverter());
        this.messageConverters.add(new StringHttpMessageConverter());
        try {
            this.messageConverters.add(new SourceHttpMessageConverter<>());
        }
        catch (Error err) {
            // Ignore when no TransformerFactory implementation is available
        }
        this.messageConverters.add(new AllEncompassingFormHttpMessageConverter());
    }

默認構造器會直接new一個StringHttpMessageConverter()加進來,不修改的話StringHttpMessageConverter的默認字符集是ISO_8859_1,一定會出現(xiàn)中文亂碼問題:

public static final Charset DEFAULT_CHARSET = StandardCharsets.ISO_8859_1;

所以我們必須找到某種方式可以定制化RequestMappingHandlerAdapter的初始化過程。

繼續(xù)分析源碼:

private void initHandlerAdapters(ApplicationContext context) {
        this.handlerAdapters = null;
        if (this.detectAllHandlerAdapters) {
            // Find all HandlerAdapters in the ApplicationContext, including ancestor contexts.
            Map<String, HandlerAdapter> matchingBeans =
                    BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
            if (!matchingBeans.isEmpty()) {
                this.handlerAdapters = new ArrayList<>(matchingBeans.values());
                // We keep HandlerAdapters in sorted order.
                AnnotationAwareOrderComparator.sort(this.handlerAdapters);
            }
        }
        else {
            try {
                HandlerAdapter ha = context.getBean(HANDLER_ADAPTER_BEAN_NAME, HandlerAdapter.class);
                this.handlerAdapters = Collections.singletonList(ha);
            }
            catch (NoSuchBeanDefinitionException ex) {
                // Ignore, we'll add a default HandlerAdapter later.
            }
        }
        // Ensure we have at least some HandlerAdapters, by registering
        // default HandlerAdapters if no other adapters are found.
        if (this.handlerAdapters == null) {
            this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
            if (logger.isTraceEnabled()) {
                logger.trace("No HandlerAdapters declared for servlet '" + getServletName() +
                        "': using default strategies from DispatcherServlet.properties");
            }
        }
    }

發(fā)現(xiàn)initHandlerAdapters方法首先會從Spring容器中獲取HandlerAdapter!

我們是否有辦法定制一個HandlerAdapter、加入到Spring容器中?Spring當然給我們提供了這種機會,回想一下@Configuration+@Bean注解,是否就可以解決?

在MvcConfig文件中增加如下代碼:

@Configuration
@ComponentScan({"org.example.controller"})
public class MvcConfiguration  {
    @Bean
    public ViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setPrefix("/WEB-INF/pages/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }
    //定制RequestMappingHandlerAdapter
    @Bean
    public RequestMappingHandlerAdapter handlerAdapter(){
        RequestMappingHandlerAdapter handlerAdapter = new RequestMappingHandlerAdapter();
        List<HttpMessageConverter<?>> messageConverters;
        messageConverters = new ArrayList<>(4);
        messageConverters.add(new ByteArrayHttpMessageConverter());
        StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(Charset.forName("UTF-8"));
        messageConverters.add(stringHttpMessageConverter);
        try {
            messageConverters.add(new SourceHttpMessageConverter<>());
        }
        catch (Error err) {
            // Ignore when no TransformerFactory implementation is available
        }
        messageConverters.add(new AllEncompassingFormHttpMessageConverter());
        handlerAdapter.setMessageConverters(messageConverters);
        return  handlerAdapter;
    }

參考RequestMappingHandlerAdapter默認構造器的代碼,修改其中StringHttpMessageConverter的創(chuàng)建過程、設置其默認字符集為UTF-8......驗證后發(fā)現(xiàn),問題已解決!

使用@EnableWebMvc

由于@EnableWebMvc是必須和@configuration配合使用的,所以,一定會存在配置類。這種情況下,配置類實現(xiàn)WebMvcConfigurer、通過擴展extendMessageConverters方法解決:

@Configuration
@EnableWebMvc
@ComponentScan({"org.example.controller"})
public class MvcConfiguration implements WebMvcConfigurer{
    public MvcConfiguration(){
        System.out.println("mvc configuration constructor...");
    }
//    通過@EnableWebMVC配置的時候起作用,
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        for(HttpMessageConverter httpMessageConverter:converters){
            if(StringHttpMessageConverter.class.isAssignableFrom(httpMessageConverter.getClass())){
                ((StringHttpMessageConverter)httpMessageConverter).setDefaultCharset(Charset.forName("UTF-8"));
            }
        }
    }
}

以上就是解決Spring MVC中文亂碼的編碼配置的詳細內容,更多關于Spring MVC中文亂碼解決的資料請關注腳本之家其它相關文章!

相關文章

  • springboot項目中后端接收前端傳參的方法示例詳解

    springboot項目中后端接收前端傳參的方法示例詳解

    這篇文章主要介紹了springboot項目中一些后端接收前端傳參的方法,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • Springboot微服務打包Docker鏡像流程解析

    Springboot微服務打包Docker鏡像流程解析

    這篇文章主要介紹了Springboot微服務打包Docker鏡像流程解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-08-08
  • springboot 整合 seata的配置過程

    springboot 整合 seata的配置過程

    本文給大家介紹springboot 整合 seata的配置過程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-08-08
  • Java之SpringBoot集成ActiveMQ消息中間件案例講解

    Java之SpringBoot集成ActiveMQ消息中間件案例講解

    這篇文章主要介紹了Java之SpringBoot集成ActiveMQ消息中間件案例講解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • Java用BigDecimal類解決Double類型精度丟失的問題

    Java用BigDecimal類解決Double類型精度丟失的問題

    這篇文章主要介紹了Java用BigDecimal類解決Double類型精度丟失的問題,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-12-12
  • springboot中如何使用minio存儲容器

    springboot中如何使用minio存儲容器

    大家好,本篇文章主要講的是springboot中如何使用minio存儲容器,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02
  • SpringBoot+Tess4j實現(xiàn)牛的OCR識別工具的示例代碼

    SpringBoot+Tess4j實現(xiàn)牛的OCR識別工具的示例代碼

    這篇文章主要介紹了SpringBoot+Tess4j實現(xiàn)牛的OCR識別工具的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-01-01
  • java如何根據HttpServletRequest獲取IP地址

    java如何根據HttpServletRequest獲取IP地址

    文章介紹了幾種代理服務器轉發(fā)服務請求頭的方法,這些請求頭可能包含真實IP地址,但并不是所有的代理都會包括這些請求頭,而且這些IP地址可能被偽造
    2025-03-03
  • Mybatis代碼生成器Mybatis Generator(MBG)實戰(zhàn)詳解

    Mybatis代碼生成器Mybatis Generator(MBG)實戰(zhàn)詳解

    本文我們主要實戰(zhàn)Mybatis官方的代碼生成器:Mybatis Generator(MBG),掌握它以后,可以簡化大部分手寫代碼,我們只需要寫復雜邏輯代碼,需要的朋友可以參考下
    2023-05-05
  • idea直接修改新的git地址的方法(圖文)

    idea直接修改新的git地址的方法(圖文)

    這篇文章主要介紹了idea直接修改新的git地址的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-07-07

最新評論