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