gpt4 book ai didi

spring-mvc - 使用 HttpMessageConverter 进行 Spring MVC 内容协商

转载 作者:行者123 更新时间:2023-12-04 06:47:02 25 4
gpt4 key购买 nike

对于最近的一个项目,我们希望为我们的响应支持 XML 和另一种格式。

但是,我们无法控制 Accept header 。因此,我们配置了一个 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 header 进行内容协商?

最佳答案

有一种解决方法,如 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>

关于spring-mvc - 使用 HttpMessageConverter 进行 Spring MVC 内容协商,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3608348/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com