Spring MVC中的UTF-8编码问题

发布于 2024-11-01 04:49:00 字数 752 浏览 1 评论 0原文

我有一个 Spring MVC bean,我想通过设置编码 UTF-8 返回土耳其字符。但虽然我的字符串是“şŞğĞіıçÇöÖüÜ”,但它返回为“??????çÇöÖüÜ”。而且当我查看响应页面(即 Internet Explorer 页面)时,编码是西欧 ISO,而不是 UTF-8。

这是代码:

    @RequestMapping(method=RequestMethod.GET,value="/GetMyList")
public @ResponseBody String getMyList(HttpServletRequest request, HttpServletResponse response) throws CryptoException{
    String contentType= "text/html;charset=UTF-8";
    response.setContentType(contentType);
    try {
        request.setCharacterEncoding("utf-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    response.setCharacterEncoding("utf-8");     
    String str="şŞğĞİıçÇöÖüÜ";
    return str;
}   

I' ve a Spring MVC bean and I would like to return turkish character by setting encoding UTF-8. but although my string is "şŞğĞİıçÇöÖüÜ" it returns as "??????çÇöÖüÜ". and also when I look at the response page, which is internet explorer page, encoding is western european iso, not UTF-8.

Here is the code:

    @RequestMapping(method=RequestMethod.GET,value="/GetMyList")
public @ResponseBody String getMyList(HttpServletRequest request, HttpServletResponse response) throws CryptoException{
    String contentType= "text/html;charset=UTF-8";
    response.setContentType(contentType);
    try {
        request.setCharacterEncoding("utf-8");
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    response.setCharacterEncoding("utf-8");     
    String str="şŞğĞİıçÇöÖüÜ";
    return str;
}   

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

独自←快乐 2024-11-08 04:49:00

我已经弄清楚了,您可以添加到请求映射 Produce = "text/plain;charset=UTF-8"

@RequestMapping(value = "/rest/create/document", produces = "text/plain;charset=UTF-8")
@ResponseBody
public void create(Document document, HttpServletRespone respone) throws UnsupportedEncodingException {

    Document newDocument = DocumentService.create(Document);

    return jsonSerializer.serialize(newDocument);
}

请参阅此博文以了解有关解决方案的更多详细信息

I've figured it out, you can add to request mapping produces = "text/plain;charset=UTF-8"

@RequestMapping(value = "/rest/create/document", produces = "text/plain;charset=UTF-8")
@ResponseBody
public void create(Document document, HttpServletRespone respone) throws UnsupportedEncodingException {

    Document newDocument = DocumentService.create(Document);

    return jsonSerializer.serialize(newDocument);
}

see this blog post for more details on the solution

权谋诡计 2024-11-08 04:49:00

在您的调度程序 servlet 上下文 xml 中,您必须添加一个属性
viewResolver bean 上的 ""
我们正在使用 freemarker 来获取视图。

它看起来像这样:

<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
       ...
       <property name="contentType" value="text/html;charset=UTF-8" />
       ...
</bean>

in your dispatcher servlet context xml, you have to add a propertie
"<property name="contentType" value="text/html;charset=UTF-8" />" on your viewResolver bean.
we are using freemarker for views.

it looks something like this:

<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
       ...
       <property name="contentType" value="text/html;charset=UTF-8" />
       ...
</bean>
原来是傀儡 2024-11-08 04:49:00

自行将 JSON 字符串转换为 UTF-8。

@RequestMapping(value = "/example.json", method = RequestMethod.GET)
@ResponseBody
public byte[] example() throws Exception {

    return "{ 'text': 'äöüß' } ".getBytes("UTF-8");
}

Convert the JSON string to UTF-8 on your own.

@RequestMapping(value = "/example.json", method = RequestMethod.GET)
@ResponseBody
public byte[] example() throws Exception {

    return "{ 'text': 'äöüß' } ".getBytes("UTF-8");
}
执笔绘流年 2024-11-08 04:49:00

在 Spring 5 或早期版本中,有 MediaType 。它已经有正确的行,如果你想遵循 DRY:

public static final String APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8";

所以我使用这套与控制器相关的注释:

@RestController
@RequestMapping(value = "my/api/url", produces = APPLICATION_JSON_UTF8_VALUE)
public class MyController {
    // ... Methods here
}

它在文档中被标记为已弃用,但我遇到了这个问题,它比复制粘贴上述内容更好我认为,在整个应用程序的每个方法/控制器上都行。

In Spring 5, or maybe in earlier versions, there is MediaType class. It has already correct line, if you want to follow DRY:

public static final String APPLICATION_JSON_UTF8_VALUE = "application/json;charset=UTF-8";

So I use this set of controller-related annotations:

@RestController
@RequestMapping(value = "my/api/url", produces = APPLICATION_JSON_UTF8_VALUE)
public class MyController {
    // ... Methods here
}

It is marked deprecated in the docs, but I've run into this issue and it is better than copy-pastying the aforementioned line on every method/controller throughout your application, I think.

被你宠の有点坏 2024-11-08 04:49:00

您需要在 RequestMapping 注释中添加字符集:

@RequestMapping(path = "/account",  produces = "application/json;charset=UTF-8")

You need add charset in the RequestMapping annotation:

@RequestMapping(path = "/account",  produces = "application/json;charset=UTF-8")
梦里人 2024-11-08 04:49:00

我发现“@RequestMapping Produces =”和其他配置更改对我没有帮助。当您执行 resp.getWriter() 时,在编写器上设置编码也为时已晚。

向 HttpServletResponse 添加标头是可行的。

@RequestMapping(value="/test", method=RequestMethod.POST)
public void test(HttpServletResponse resp) {
    try {
        resp.addHeader("content-type", "application/json; charset=utf-8");
        PrintWriter w = resp.getWriter();
        w.write("{\"name\" : \"μr μicron\"}");
        w.flush();
        w.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

I found that "@RequestMapping produces=" and other configuration changes didn't help me. By the time you do resp.getWriter(), it is also too late to set the encoding on the writer.

Adding a header to the HttpServletResponse works.

@RequestMapping(value="/test", method=RequestMethod.POST)
public void test(HttpServletResponse resp) {
    try {
        resp.addHeader("content-type", "application/json; charset=utf-8");
        PrintWriter w = resp.getWriter();
        w.write("{\"name\" : \"μr μicron\"}");
        w.flush();
        w.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}
栀梦 2024-11-08 04:49:00

还有一些类似的问题:Spring MVC响应编码问题使用 @ResponseBody 自定义 HttpMessageConverter 来执行 Json 操作

然而,我的简单解决方案:

@RequestMapping(method=RequestMethod.GET,value="/GetMyList")
public ModelAndView getMyList(){
  String test = "čćžđš";
  ...
  ModelAndView mav = new ModelAndView("html_utf8");
  mav.addObject("responseBody", test);
}

并且视图 html_utf8.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>${responseBody}

没有额外的类和配置。
您还可以为其他内容类型创建另一个视图(例如 json_utf8)。

There are some similar questions: Spring MVC response encoding issue, Custom HttpMessageConverter with @ResponseBody to do Json things.

However, my simple solution:

@RequestMapping(method=RequestMethod.GET,value="/GetMyList")
public ModelAndView getMyList(){
  String test = "čćžđš";
  ...
  ModelAndView mav = new ModelAndView("html_utf8");
  mav.addObject("responseBody", test);
}

and the view html_utf8.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>${responseBody}

No additional classes and configuration.
And You can also create another view (for example json_utf8) for other content type.

笑,眼淚并存 2024-11-08 04:49:00

我通过将生成的返回类型推断到第一个 GET requestMethod 中解决了这个问题。这里重要的部分是

produces="application/json;charset=UTF-8

所以每一个如何使用/account/**,Spring都会返回application/json;charset=UTF-8内容类型。

@Controller
@Scope("session") 
@RequestMapping(value={"/account"}, method = RequestMethod.GET,produces="application/json;charset=UTF-8")
public class AccountController {

   protected final Log logger = LogFactory.getLog(getClass());

   ....//More parameters and method here...

   @RequestMapping(value={"/getLast"}, method = RequestMethod.GET)
   public @ResponseBody String getUltimo(HttpServletResponse response) throws JsonGenerationException, JsonMappingException, IOException{

      ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter();
      try {
        Account account = accountDao.getLast();
        return writer.writeValueAsString(account);
      }
      catch (Exception e) {
        return errorHandler(e, response, writer);
      }
}

因此,您不必为控制器中的每个方法进行设置,您可以为整个类进行设置。如果您需要对特定方法进行更多控制,则只需推断生成的返回内容类型即可。

I've resolved this issue by inferring the produced return type into the first GET requestMethod. The important part here is the

produces="application/json;charset=UTF-8

So every one how use /account/**, Spring will return application/json;charset=UTF-8 content type.

@Controller
@Scope("session") 
@RequestMapping(value={"/account"}, method = RequestMethod.GET,produces="application/json;charset=UTF-8")
public class AccountController {

   protected final Log logger = LogFactory.getLog(getClass());

   ....//More parameters and method here...

   @RequestMapping(value={"/getLast"}, method = RequestMethod.GET)
   public @ResponseBody String getUltimo(HttpServletResponse response) throws JsonGenerationException, JsonMappingException, IOException{

      ObjectWriter writer = new ObjectMapper().writer().withDefaultPrettyPrinter();
      try {
        Account account = accountDao.getLast();
        return writer.writeValueAsString(account);
      }
      catch (Exception e) {
        return errorHandler(e, response, writer);
      }
}

So, you do not have to set up for each method in your Controller, you can do it for the entire class. If you need more control over a specific method, you just only have to infer the produces return content type.

失而复得 2024-11-08 04:49:00

还要添加到您的 bean 中:

   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <array>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg index="0" name="defaultCharset" value="UTF-8"/>
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded;charset=UTF-8</value>
                    </list>
                </property>
        </bean></bean>

对于 @ExceptionHandler :

enter code<bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
    <property name="messageConverters">
        <array>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg index="0" name="defaultCharset" value="UTF-8"/>
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </array>
    </property>
</bean>

如果您使用 它应该在 beans 之后。

Also add to your beans :

   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <array>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg index="0" name="defaultCharset" value="UTF-8"/>
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded;charset=UTF-8</value>
                    </list>
                </property>
        </bean></bean>

For @ExceptionHandler :

enter code<bean class="org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver">
    <property name="messageConverters">
        <array>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg index="0" name="defaultCharset" value="UTF-8"/>
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <value>text/plain;charset=UTF-8</value>
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                        <value>application/x-www-form-urlencoded;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
        </array>
    </property>
</bean>

If you use <mvc:annotation-driven/> it should be after beans.

下雨或天晴 2024-11-08 04:49:00

如果您使用的是 Spring MVC 版本 5,您还可以使用 @GetMapping 注释来设置编码。下面是一个将内容类型设置为 JSON 并将编码类型设置为 UTF-8 的示例:

@GetMapping(value="/rest/events", produces = "application/json; charset=UTF-8")

有关 @GetMapping 注释的更多信息,请参见:

https://docs.spring.io/spring-framework/docs/current/javadoc-api/ org/springframework/web/bind/annotation/GetMapping.html

If you are using Spring MVC version 5 you can set the encoding also using the @GetMapping annotation. Here is an example which sets the content type to JSON and also the encoding type to UTF-8:

@GetMapping(value="/rest/events", produces = "application/json; charset=UTF-8")

More information on the @GetMapping annotation here:

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/bind/annotation/GetMapping.html

清醇 2024-11-08 04:49:00

当您尝试发送特殊字符(如 è、à、ù 等)时,您可能会在 Jsp Post 页面中看到许多字符,如“£”、“Ä”或“Æ”​​。
要在 99% 的情况下解决此问题,您可以在 web.xml 中将这段代码移至文件头部:

   <filter>
        <filter-name>encodingFilter</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>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

有关完整示例,请参见此处:https://lentux-informatica.com/spring-mvc-utf-8-encoding-problem-solved/

When you try to send special characters like è,à,ù, etc etc, may be you see in your Jsp Post page many characters like '£','Ä’ or ‘Æ’.
To solve this problem in 99% of cases you may move in your web.xml this piece of code at the head of file:

   <filter>
        <filter-name>encodingFilter</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>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

For complete example see here : https://lentux-informatica.com/spring-mvc-utf-8-encoding-problem-solved/

诗酒趁年少 2024-11-08 04:49:00

如果使用 Spring Boot,只需将此属性添加到您的 applications.properties 文件中:

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true

If are using spring boot just add this properies to your applications.properties file:

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true
鲜肉鲜肉永远不皱 2024-11-08 04:49:00

如果您使用 Spring Boot(使用 3.0.4 进行测试),则默认情况下 UTF-8 对于 HTTP POST 请求和响应都将开箱即用。

如果您手动添加了 Spring MVC,那么您需要配置两件事:

  1. CharacterEncodingFilter:一个 Spring Web servlet 过滤器,允许您:

指定请求的字符编码。这很有用,因为当前的浏览器通常不会设置字符编码,即使在 HTML 页面或表单中指定也是如此。

  1. StringHttpMessageConverter:一个 Spring HttpMessageConverter,允许您更改响应 Content-Type HTTP 标头字段。如果没有这个,Content-Type 标头通常会是 text/html;charset=ISO-8859-1 而不是 UTF-8。

如何设置CharacterEncodingFilter?

这取决于您的网络应用程序配置。您应该研究一下如何设置 Servlet 过滤器。对于 CharacterEncodingFilter,您需要将 encoding 参数设置为 utf-8,将 forceEncoding 设置为 正确。

例如,如果您使用 web.xml 来配置 Servlet 过滤器,那么您可以在 web.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>forceEncoding</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>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

如果这不起作用(意味着,您的 MVC 控制器不会接收 UTF-8 格式的请求参数),那么您需要将 characterEncodingFilter 移至 web.xml 中的更高位置,以便在之前调用它其他过滤器。

如何设置StringHttpMessageConverter?

更改/添加您的 WebMvcConfigurer 如下:

import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.StandardCharsets;
import java.util.List;

public class MyCustomWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
    }
}

它默认使用 StandardCharsets.ISO_8859_1,但上面的代码会将其更改为 UTF-8。您可以通过检查 HTTP 响应中的 Content-Type 标头来验证这是否有效。现在应该显示 text/html;charset=UTF-8 而不是 text/html;charset=ISO-8859-1

If you are using Spring Boot (tested with 3.0.4), then UTF-8 will work out of the box by default for both HTTP POST requests and responses.

If you have manually added Spring MVC, then you'll need to configure two things:

  1. CharacterEncodingFilter: a Spring Web servlet filter that allows you to:

specify a character encoding for requests. This is useful because current browsers typically do not set a character encoding even if specified in the HTML page or form.

  1. StringHttpMessageConverter: a Spring HttpMessageConverter that allows you to change the response Content-Type HTTP header field. Without this, the Content-Type header will usually be text/html;charset=ISO-8859-1 instead of UTF-8.

How to set CharacterEncodingFilter?

It depends on your web app configuration. You should look into how you can set a Servlet Filter in general. For CharacterEncodingFilter you'll need to set the encoding param to utf-8 and the forceEncoding to true.

For example, if you are using web.xml to configure Servlet Filters, then you could use something like this in your web.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>forceEncoding</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>
        <dispatcher>REQUEST</dispatcher>
    </filter-mapping>

If this doesn't work (meaning, your MVC controller doesn't receive request parameters as UTF-8), then you need to move the characterEncodingFilter higher up in web.xml, so that it gets called before other filters.

How to set StringHttpMessageConverter?

Change/add your WebMvcConfigurer to something like this:

import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.nio.charset.StandardCharsets;
import java.util.List;

public class MyCustomWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        converters.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
    }
}

It uses StandardCharsets.ISO_8859_1 by default, but the code above will change it to UTF-8. You can verify if this is working, by checking the Content-Type header in the HTTP responses. Which should now show text/html;charset=UTF-8 instead of text/html;charset=ISO-8859-1.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文