谁在S​​pring MVC中设置响应内容types(@ResponseBody)

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

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

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

即使当我的浏览器发送

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

我用某种方式默认configuration的spring

我已经find了将这个bean添加到configuration的提示,但是我认为它没有被使用,因为它说它不支持编码,而是使用默认的编码。

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

我的控制器代码是(请注意,这种响应types的变化不适合我):

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

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

我find了Spring 3.1的解决scheme。 使用@ResponseBody注释。 以下是使用Json输出的控制器的示例:

 @RequestMapping(value = "/getDealers", method = RequestMethod.GET, produces = "application/json; charset=utf-8") @ResponseBody public String sendMobileData() { } 

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

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

 @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 ... } } 

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

 @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比这个更好。

您可以将Request =“text / plain; charset = UTF-8”添加到RequestMapping

 @RequestMapping(value = "/rest/create/document", produces = "text/plain;charset=UTF-8") @ResponseBody public String create(Document document, HttpServletRespone respone) throws UnsupportedEncodingException { Document newDocument = DocumentService.create(Document); return jsonSerializer.serialize(newDocument); } 

看到这个博客更多的细节

我最近在和这个问题作斗争,发现在Spring 3.1中有更好的答案:

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

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

我在ContentNegotiatingViewResolver bean的MarshallingView中设置了内容types。 它工作容易,清洁和平稳:

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

我正在使用在web.xml中configuration的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> 

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

 @RequestMapping(value = "/aURLMapping.htm", method = RequestMethod.GET, produces = "text/html; charset=utf-8") public @ResponseBody String getMobileData() { } 

由于digz6666,你的解决scheme适用于我稍作修改,因为我使用的是json:

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

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

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

如果以上都没有为你工作,尝试在“POST”而不是“GET”,这对我很好地工作ajax请求…以上都没有。 我也有characterEncodingFilter。

 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.1中解决这个问题的简单方法是:在servlet-context.xml添加以下configuration代码

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

不需要重写或执行任何操作。

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

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

 <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标签。 否则,configuration可能无效。

 public final class ConfigurableStringHttpMessageConverter extends AbstractHttpMessageConverter<String> { private Charset defaultCharset; public Charset getDefaultCharset() { return defaultCharset; } private final List<Charset> availableCharsets; private boolean writeAcceptCharset = true; public ConfigurableStringHttpMessageConverter() { super(new MediaType("text", "plain", StringHttpMessageConverter.DEFAULT_CHARSET), MediaType.ALL); defaultCharset = StringHttpMessageConverter.DEFAULT_CHARSET; this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values()); } public ConfigurableStringHttpMessageConverter(String charsetName) { super(new MediaType("text", "plain", Charset.forName(charsetName)), MediaType.ALL); defaultCharset = Charset.forName(charsetName); this.availableCharsets = new ArrayList<Charset>(Charset.availableCharsets().values()); } /** * Indicates whether the {@code Accept-Charset} should be written to any outgoing request. * <p>Default is {@code true}. */ public void setWriteAcceptCharset(boolean writeAcceptCharset) { this.writeAcceptCharset = writeAcceptCharset; } @Override public boolean supports(Class<?> clazz) { return String.class.equals(clazz); } @Override protected String readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException { Charset charset = getContentTypeCharset(inputMessage.getHeaders().getContentType()); return FileCopyUtils.copyToString(new InputStreamReader(inputMessage.getBody(), charset)); } @Override protected Long getContentLength(String s, MediaType contentType) { Charset charset = getContentTypeCharset(contentType); try { return (long) s.getBytes(charset.name()).length; } catch (UnsupportedEncodingException ex) { // should not occur throw new InternalError(ex.getMessage()); } } @Override protected void writeInternal(String s, HttpOutputMessage outputMessage) throws IOException { if (writeAcceptCharset) { outputMessage.getHeaders().setAcceptCharset(getAcceptedCharsets()); } Charset charset = getContentTypeCharset(outputMessage.getHeaders().getContentType()); FileCopyUtils.copy(s, new OutputStreamWriter(outputMessage.getBody(), charset)); } /** * Return the list of supported {@link Charset}. * * <p>By default, returns {@link Charset#availableCharsets()}. Can be overridden in subclasses. * * @return the list of accepted charsets */ protected List<Charset> getAcceptedCharsets() { return this.availableCharsets; } private Charset getContentTypeCharset(MediaType contentType) { if (contentType != null && contentType.getCharSet() != null) { return contentType.getCharSet(); } else { return defaultCharset; } } } 

示例configuration:

  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <util:list> <bean class="ru.dz.mvk.util.ConfigurableStringHttpMessageConverter"> <constructor-arg index="0" value="UTF-8"/> </bean> </util:list> </property> </bean>