对于最近的项目,我们希望支持XML和我们的resopnses的另一种格式。
但是,我们无法控制Accept标头。因此,我们将ContentNegotiatingViewResolver配置为使用请求参数:
<bean id="viewResolver" class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
<property name="favorParameter" value="true" />
<property name="parameterName" value="format" />
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="application/xml" />
<property name="mediaTypes">
<map>
<entry key="xml" value="application/xml" />
<entry key="foo" value="application/x-foo" />
</map>
</property>
<property name="viewResolvers">
<list>
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" >
<property name="basename" value="views-xml" />
</bean>
<bean class="org.springframework.web.servlet.view.ResourceBundleViewResolver" >
<property name="basename" value="views-foo" />
</bean>
</list>
</property>
</bean>
现在,我想知道我是否可以使用@ResponseBody和HttpMessageConverter实现来简化我需要维护的代码量。
但是,是否有类似的方法来确保将reqeust参数用于内容协商而不是Accept标头?
答案 0 :(得分:3)
有一种解决方法,如https://jira.springframework.org/browse/SPR-7517
所述创建AnnotationMethodHandlerAdapter的子类:
package org.nkl.spring;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter;
public class MyAnnotationMethodHandlerAdapter extends AnnotationMethodHandlerAdapter {
private Logger logger = LoggerFactory.getLogger(MyAnnotationMethodHandlerAdapter.class);
private String requestParam = "accept";
private Map<String, MediaType> mediaTypesMap;
@Override protected HttpInputMessage createHttpInputMessage(HttpServletRequest request) throws Exception {
HttpInputMessage message = super.createHttpInputMessage(request);
String accept = request.getParameter(requestParam);
if (accept == null || accept.isEmpty()) {
logger.info(String.format("Request parameter [%s] not found. Using standard HttpInputMessage", requestParam));
return message;
} else {
logger.info(String.format("Request parameter [%s] was [%s]", requestParam, accept));
MediaType mediaType = mediaTypesMap.get(accept);
if (mediaType == null) {
logger.info(String.format("Suitable MediaType not found. Using standard HttpInputMessage"));
return message;
} else {
logger.info(String.format("Suitable MediaType [%s] found. Using custom HttpInputMessage", mediaType));
return new MyHttpInputMessage(message, mediaTypesMap.get(accept));
}
}
}
public void setMediaTypesMap(Map<String, MediaType> mediaTypesMap) {
this.mediaTypesMap = mediaTypesMap;
}
public void setRequestParam(String requestParam) {
this.requestParam = requestParam;
}
}
创建HttpInputMessage的装饰器:
package org.nkl.spring;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
public class MyHttpInputMessage implements HttpInputMessage {
private HttpInputMessage delegate;
public MyHttpInputMessage(HttpInputMessage delagate, MediaType mediaType) {
this.delegate = delagate;
this.delegate.getHeaders().setAccept(Arrays.asList(mediaType));
}
@Override public InputStream getBody() throws IOException {
return this.delegate.getBody();
}
@Override public HttpHeaders getHeaders() {
return this.delegate.getHeaders();
}
}
配置您的bean,如:
<bean class="org.nkl.spring.MyAnnotationMethodHandlerAdapter">
<property name="requestParam" value="format" />
<property name="mediaTypesMap">
<util:map>
<entry key="plain" value="text/plain" />
<entry key="xml" value="text/xml" />
</util:map>
</property>
<property name="messageConverters">
<util:list>
... converters go here ...
</util:list>
</property>
</bean>
答案 1 :(得分:0)
更新版本的Spring现在可以执行此操作。 ContentNegotiationManagerFactoryBean
可以创建一个内容协商管理器,可以在此处执行您想要的操作。查看我的answer to a related question。