繁体   English   中英

Spring MVC中的UTF-8编码问题

[英]UTF-8 encoding problem in Spring MVC

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

我已经想通了,您可以添加到请求映射生成 = "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);
}

有关解决方案的更多详细信息,请参阅此博客文章

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

它看起来像这样:

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

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

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

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

在 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
}

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

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

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

就这样。

还有一些类似的问题: Spring MVC 响应编码问题Custom 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)。

我已经通过将生成的返回类型推断为第一个 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);
      }
}

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

还要添加到您的豆子中:

   <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>

如果你使用<mvc:annotation-driven/>它应该在 bean 之后。

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

当您尝试发送 è、à、ù 等特殊字符时,您可能会在 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/

我发现“@RequestMapping 生成=”和其他配置更改对我没有帮助。 当您执行 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();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM