После обновления Spring Boot 2.2.4 есть изменения при возврате jsoncontent-typeЗависит отapplication/json;charset=UTF-8сталapplication/json;
И это приведет к искажению символов в приложениях, кодировка которых по умолчанию не UTF-8.
причина
Так почему? Основная причинаJackson2CodecSupportизDEFAULT_MIME_TYPESудаленныйCharsetвариант, поэтому на выходе не будетCharsetохватывать
Итак, как Spring определяетContent-Typeчто о? Можно ли его добавить посередине?
Анализируя ссылку вызова, можно обнаружить, чтоEncoderHttpMessageWriterсделал updateContentType
Так как его обновить?
Видно, что он сначала берется из MessageHeader, если не получен, то используется дефолт, если дефолта нет, то используется дефолт.AbstractMessageWriterResultHandlerВыберите лучший MediaType
Так что же по умолчанию?
Это первый MimeType кодировщика, а кодирование по умолчанию для Json —Jackson2JsonEncoderследовательноJackson2CodecSupportУдаленная кодировка повлияет на реальный вывод запроса.
решение
Из вышеизложенного видно, что решение очень простое.Есть два типа.Один из них заключается в добавлении пользовательского кодировщика.Мимовый тип пользовательского кодировщика по умолчанию можно добавить с помощью charset.
Однако стоимость этого метода слишком высока, и улучшить тестирование пользовательского кодировщика сложнее.
Итак, второе, добавьте его в заголовок ответа.Content-TypeСтаньте первым выбором, это тоже относительно просто, просто добавьте WebFilter
После его добавления в нормальном выводе есть Charset, но после запуска теста выясняется, что проблема с ненормальной ссылкой все равно есть, а charset нет.Почему так?
Отслеживая исходный код, получается, что RequestMappingHandlerAdapter будет очищать все заголовки, связанные с Content, при обработке исключений.На данный момент цепочка фильтров завершена.Если вы хотите переписать, вы можете переписать только HandlerResultHandler.
Переписывать HandlerResultHandler слишком громоздко, а переписывать для каждого вывода дорого.
Поэтому я не придумал хорошего способа, поэтому я принял метод Хака и переписал его с помощью размышлений.Jackson2CodecSupportизDEFAULT_MIME_TYPES
Связанные знания - ссылка на обработку запроса в WebFlux
Как видно из документации Spring, ядром под WebFLux являетсяHttpHandlerа такжеWebHandler, сетевой фреймворк (netty, tomcat или другой) получает запрос и передает его HttpHandler, а затем вызывает окончательный WebHandler.
Так как же устроен HttpHandler?
Видно, что сначала он получает окончательный webHandler и цепочку фильтров для построения декорированного, а затем оборачивает обработчики исключений и, наконец, становится HttpWebHandlerAdapter для прямого подключения к сетевой структуре.
Когда сетевая структура ответит на изменение состояния канала, она вызовет метод обработчика HttpWebHandlerAdapter, а затем, в свою очередь, вызовет цепочку ответственности.
Как показано на рисунке выше, видно, что когдаRequestMappingHandlerAdapterизhandleException, цепочка фильтров уже была завершена, поэтому наш ContentTyPilter недействителен