java mvc教程 - 谁在S pring MVC中设置响应内容类型(@ResponseBody)





springmvc官网 mvc是什么 (14)


根据link “如果未指定字符编码,则Servlet规范要求使用ISO-8859-1的编码”。如果您使用的是Spring 3.1或更高版本,则使用下面的配置将charset = UTF-8设置为应对机构
@RequestMapping(value =“你的映射url”,产生=“text / plain; charset = UTF-8”)

我在Annotation驱动的Spring MVC Java Web应用程序上运行了jetty web服务器(目前在maven jetty插件中)。

我想用一个只返回字符串帮助文本的控制器方法来做一些AJAX支持。 资源采用UTF-8编码,字符串也是如此,但我的服务器响应随附

content-encoding: text/plain;charset=ISO-8859-1 

即使我的浏览器发送

Accept-Charset  windows-1250,utf-8;q=0.7,*;q=0.7

我使用某种方式默认的弹簧配置

我发现了将这个bean添加到配置中的提示,但我认为它没有被使用,因为它表示它不支持编码,而是使用默认的编码。

<bean class="org.springframework.http.converter.StringHttpMessageConverter">
    <property name="supportedMediaTypes" value="text/plain;charset=UTF-8" />
</bean>

我的控制器代码是(请注意,这种响应类型的变化对我来说不起作用):

@RequestMapping(value = "ajax/gethelp")
public @ResponseBody String handleGetHelp(Locale loc, String code, HttpServletResponse response) {
    log.debug("Getting help for code: " + code);
    response.setContentType("text/plain;charset=UTF-8");
    String help = messageSource.getMessage(code, null, loc);
    log.debug("Help is: " + help);
    return help;
}



我在ContentNegotiatingViewResolver bean的MarshallingView中设置了内容类型。 它工作容易,清洁和流畅:

<property name="defaultViews">
  <list>
    <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
      <constructor-arg>
        <bean class="org.springframework.oxm.xstream.XStreamMarshaller" />     
      </constructor-arg>
      <property name="contentType" value="application/xml;charset=UTF-8" />
    </bean>
  </list>
</property>



以防万一您也可以通过以下方式设置编码:

@RequestMapping(value = "ajax/gethelp")
public ResponseEntity<String> handleGetHelp(Locale loc, String code, HttpServletResponse response) {
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.add("Content-Type", "text/html; charset=utf-8");

    log.debug("Getting help for code: " + code);
    String help = messageSource.getMessage(code, null, loc);
    log.debug("Help is: " + help);

    return new ResponseEntity<String>("returning: " + help, responseHeaders, HttpStatus.CREATED);
}

我认为使用StringHttpMessageConverter比这更好。




请注意,在Spring MVC 3.1中,您可以使用MVC命名空间来配置消息转换器:

<mvc:annotation-driven>
  <mvc:message-converters register-defaults="true">
    <bean class="org.springframework.http.converter.StringHttpMessageConverter">
      <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
    </bean>
  </mvc:message-converters>
</mvc:annotation-driven>

或基于代码的配置:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

  private static final Charset UTF8 = Charset.forName("UTF-8");

  @Override
  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
    stringConverter.setSupportedMediaTypes(Arrays.asList(new MediaType("text", "plain", UTF8)));
    converters.add(stringConverter);

    // Add other converters ...
  }
}



您可以使用产品来指示您从控制器发送的响应的类型。 这个“生成”关键字在ajax请求中最有用,对我的项目非常有用

@RequestMapping(value = "/aURLMapping.htm", method = RequestMethod.GET, produces = "text/html; charset=utf-8") 

public @ResponseBody String getMobileData() {

}



感谢digz6666,你的解决方案适用于我,因为我使用了json:

responseHeaders.add("Content-Type", "application/json; charset=utf-8");

axtavt给出的答案(你推荐的)不会为我工作。 即使我添加了正确的媒体类型:

if (conv instanceof StringHttpMessageConverter) {                   
                    ((StringHttpMessageConverter) conv).setSupportedMediaTypes(
                        Arrays.asList(
                                new MediaType("text", "html", Charset.forName("UTF-8")),
                                new MediaType("application", "json", Charset.forName("UTF-8")) ));
                }



如果您决定通过以下配置解决此问题:

<mvc:annotation-driven>
  <mvc:message-converters register-defaults="true">
    <bean class="org.springframework.http.converter.StringHttpMessageConverter">
      <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
    </bean>
  </mvc:message-converters>
</mvc:annotation-driven>

你应该确认你的所有* .xml文件中只应该有一个mvc:annotation-driven标签。 否则,配置可能无效。




package com.your.package.spring.fix;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;

/**
 * @author Szilard_Jakab (JaKi)
 * Workaround for Spring 3 @ResponseBody issue - get incorrectly 
   encoded parameters     from the URL (in example @ JSON response)
 * Tested @ Spring 3.0.4
 */
public class RepairWrongUrlParamEncoding {
    private static String restoredParamToOriginal;

    /**
    * @param wrongUrlParam
    * @return Repaired url param (UTF-8 encoded)
    * @throws UnsupportedEncodingException
    */
    public static String repair(String wrongUrlParam) throws 
                                            UnsupportedEncodingException {
    /* First step: encode the incorrectly converted UTF-8 strings back to 
                  the original URL format
    */
    restoredParamToOriginal = URLEncoder.encode(wrongUrlParam, "ISO-8859-1");

    /* Second step: decode to UTF-8 again from the original one
    */
    return URLDecoder.decode(restoredParamToOriginal, "UTF-8");
    }
}

在我为这个问题尝试了很多解决方法之后..我想到了这一点,它工作正常。




我最近在解决这个问题,并在Spring 3.1中找到了更好的答案:

@RequestMapping(value = "ajax/gethelp", produces = "text/plain")

因此,像JAX-RS一样简单,就像所有意见表明它可以/应该是一样。




在Spring 3.1.1中解决这个问题的简单方法是:在servlet-context.xml添加以下配置代码

    <annotation-driven>
    <message-converters register-defaults="true">
    <beans:bean class="org.springframework.http.converter.StringHttpMessageConverter">
    <beans:property name="supportedMediaTypes">    
    <beans:value>text/plain;charset=UTF-8</beans:value>
    </beans:property>
    </beans:bean>
    </message-converters>
    </annotation-driven>

不需要覆盖或执行任何操作。




StringHttpMessageConverter bean的简单声明是不够的,你需要将它注入到AnnotationMethodHandlerAdapter

<bean class = "org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
        <array>
            <bean class = "org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
            </bean>
        </array>
    </property>
</bean>

然而,使用这种方法你必须重新定义所有的HttpMessageConverter ,并且它不能和<mvc:annotation-driven />

所以,也许最方便但很难看的方法是用BeanPostProcessor拦截AnnotationMethodHandlerAdapter实例化:

public class EncodingPostProcessor implements BeanPostProcessor {
    public Object postProcessBeforeInitialization(Object bean, String name)
            throws BeansException {
        if (bean instanceof AnnotationMethodHandlerAdapter) {
            HttpMessageConverter<?>[] convs = ((AnnotationMethodHandlerAdapter) bean).getMessageConverters();
            for (HttpMessageConverter<?> conv: convs) {
                if (conv instanceof StringHttpMessageConverter) {
                    ((StringHttpMessageConverter) conv).setSupportedMediaTypes(
                        Arrays.asList(new MediaType("text", "html", 
                            Charset.forName("UTF-8"))));
                }
            }
        }
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String name)
            throws BeansException {
        return bean;
    }
}

-

<bean class = "EncodingPostProcessor " />



我正在使用在web.xml中配置的CharacterEncodingFilter。 也许这有帮助。

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



如果以上都没有为你工作尝试在“POST”而不是“GET”上发出ajax请求,那么对我来说工作很好......以上都没有。 我也有characterEncodingFilter。




一些(设计糟糕的)网站有最大密码长度,原因很简单:这是他们在数据库中存储密码的所有空间。 他们很可能不会对它进行散列或处理它,这意味着它以纯文本形式存储。 这样的网站我每次使用一次,丢弃密码。 这是一个糟糕的设计,不幸的是人们仍然使用它。





java web-applications spring-mvc character-encoding