【问题标题】:UTF-8 encoding problem in Spring MVCSpring MVC 中的 UTF-8 编码问题
【发布时间】:2011-08-04 16:39:46
【问题描述】:

我有一个 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;
}   

【问题讨论】:

标签: java spring-mvc utf-8 character-encoding


【解决方案1】:

我想通了,你可以添加到请求映射中产生 = "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

【讨论】:

  • 链接博客文章的解决方案 1 对我有用,即将字节写入输出流。其他两个解决方案对我不起作用。
  • 对我来说,它有效,我一直在寻找解决方案。谢谢。
  • @rwitzel 也许你也需要这个:response.setCharacterEncoding("UTF-8");我有过滤器。
  • 对我来说,“链接博客文章的解决方案 1 对我有用,即将字节写入输出流。其他两个解决方案对我不起作用。”
  • 该网站不再托管。我在这篇博文中添加了解决方案 1 monsterbrain.github.io/2019/04/01/spring-mvc-ajax-utf-8-problem
【解决方案2】:

在您的调度程序 servlet 上下文 xml 中,您必须添加一个属性 "<property name="contentType" value="text/html;charset=UTF-8" />" 在您的 viewResolver bean 上。 我们正在使用 freemarker 进行视图。

看起来像这样:

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

【讨论】:

  • 还解决了我的 Thymeleaf 问题。谢谢。
【解决方案3】:

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

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

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

【讨论】:

  • 唯一对我有用的解决方案,使用response.getOutputStream().write(jsonObject.toString().getBytes("UTF-8"));
【解决方案4】:

在 Spring 5 中,或者可能在早期版本中,有 MediaType class。如果你想遵循 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
}

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

【讨论】:

  • 自 5.2 起已弃用,请参阅 docs.spring.io
  • @Vala.D.感谢您指出了这一点。当我使用这个选项时,我们肯定使用的是 som 5.0.* 版本,并计划转移到 IIRC 的 5.1.* 分支。尽管如此,这仍然是他们决定弃用它的一些有争议的原因,因为我们在使用一些类似 rest 的服务进行编码时遇到了问题。与“现代浏览器”不同,这些内部网络服务有时往往是遗留的。 :D
  • 我在休息服务方面遇到了同样的问题,这就是我最初来到这里的原因。
【解决方案5】:

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

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

【讨论】:

    【解决方案6】:

    还有一些类似的问题:Spring MVC response encoding issueCustom HttpMessageConverter with @ResponseBody to do Json things

    但是,我的简单解决方案:

    @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)。

    【讨论】:

      【解决方案7】:

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

      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);
            }
      }
      

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

      【讨论】:

        【解决方案8】:

        还可以添加到您的 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>
        

        如果你使用&lt;mvc:annotation-driven/&gt;,它应该在beans之后。

        【讨论】:

          【解决方案9】:

          如果您使用的是 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

          【讨论】:

            【解决方案10】:

            当您尝试发送 è、à、ù 等特殊字符时,您可能会在 Jsp 帖子页面中看到许多字符,例如 '£'、'Ä' 或 'Æ'。 要在 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/

            【讨论】:

              【解决方案11】:

              我发现“@RequestMappingproduce=”和其他配置更改对我没有帮助。到你做 resp.getWriter() 的时候,在 writer 上设置编码也为时已晚。

              向 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();
                  }
              }
              

              【讨论】:

                猜你喜欢
                • 2019-10-02
                • 2011-07-05
                • 2011-08-21
                • 2016-01-08
                • 2011-11-02
                • 2017-04-27
                • 1970-01-01
                • 2010-12-01
                相关资源
                最近更新 更多