java - 在 Spring MVC 中通过配置验证格式参数

标签 java json spring spring-mvc content-type

这是我的情况:

我将我的 Web 服务的 mvc-config.xml 文件设置为将 JSON 作为默认媒体类型。我也将 ContentNegotiatingViewResolver 的 favorParameter 设置为 true。此外,我将 useNotAcceptableStatusCode 设置为 true,以便不接受的格式将返回 406。

我的问题是:当有人传入 Not Acceptable 格式参数 (format=foo) 时,有没有办法在配置中触发 406 状态代码?还是必须用代码来完成?

这是配置文件:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <bean
        class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
        <property name="mediaTypes">
            <map>
                <entry key="json" value="application/json" />
                <entry key="xml" value="application/xml" />
            </map>
        </property>
        <property name="defaultViews">
            <list>
                <bean class="com.work.stuff.web.view.json.ExtendedMappingJacksonJsonView">
                    <property name="objectMapper">
                        <ref bean="JacksonObjectMapper" />
                    </property>
                </bean>
                <bean class="org.springframework.web.servlet.view.xml.MarshallingView">
                    <property name="marshaller">
                        <ref bean="Jaxb2Marshaller" />
                    </property>
                </bean>
            </list>
        </property>
        <property name="defaultContentType" value="application/json" />
        <property name="favorParameter" value="true" />
        <property name="useNotAcceptableStatusCode" value="true" />
    </bean>

    <bean
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean
                    class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
                    <property name="objectMapper">
                        <ref bean="JacksonObjectMapper" />
                    </property>
                </bean>
                <ref bean="marshallingHttpMessageConverter" />
            </list>
        </property>
    </bean>

    <bean id="marshallingHttpMessageConverter"
        class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
        <property name="marshaller" ref="Jaxb2Marshaller" />
        <property name="unmarshaller" ref="Jaxb2Marshaller" />
    </bean>
    <bean id="JacksonObjectMapper" class="org.codehaus.jackson.map.ObjectMapper" />
    <bean id="JacksonSerializationConfig" class="org.codehaus.jackson.map.SerializationConfig"
        factory-bean="JacksonObjectMapper" factory-method="getSerializationConfig" />
    <bean
        class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject" ref="JacksonSerializationConfig" />
        <property name="targetMethod" value="setSerializationInclusion" />
        <property name="arguments">
            <list>
                <value type="org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion">NON_NULL</value>
            </list>
        </property>
    </bean>
    <bean id="Jaxb2Marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
        <property name="classesToBeBound">
            <list>
                <value>com.work.stuff.Concepts</value>
                <value>com.work.stuff.Concept</value>
                <value>com.work.stuff.Terms</value>
                <value>com.work.stuff.Term</value>
                <value>com.work.stuff.Namespaces</value>
                <value>com.work.stuff.Namespace</value>
                <value>com.work.stuff.Subsets</value>
                <value>com.work.stuff.Subset</value>
                <value>com.work.stuff.Associations</value>
                <value>com.work.stuff.Association</value>
            </list>
        </property>
    </bean>
</beans>

最佳答案

ContentNegotiatingViewResolver 似乎不支持这种行为。目前,我认为最好的办法是对其进行子类化并覆盖 getMediaTypeFromParameter() 方法以在不支持媒体类型时抛出异常。

您可以从该方法中抛出任何RuntimeException,如果您使用@ResponseStatus 注释异常类,您可以控制HTTP 响应代码,例如

@ResponseStatus(HttpStatus.NOT_ACCEPTABLE)
public class FormatNotSupportedException extends RuntimeException {
}

从长远来看,我强烈建议您使用 http://jira.springsource.org 提交问题,要求将此类功能添加到 ContentNegotiatingViewResolver。他们应该能够将其添加为可选的行为参数。像这样的请求意味着 Spring 不断变得更好。

关于java - 在 Spring MVC 中通过配置验证格式参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3661769/

相关文章:

java - 从 Java 读取 JSON

android - 如何在 android 中创建嵌套的动态 Json 对象 pojo 类

spring - 为什么 Spring 框架不赞成使用 Guava 缓存?

java - 在 CXF Spring Boot 中注册过滤器

java - 由于内存不足,Ubuntu 内核终止了 CPLEX ILP 进程

java - 在 Android 应用程序中共享 ArrayList<Custom>

java - 快速排序方法给我一个 stackoverflowerror?

php - 使用 PHP 将 CSV 转换为 JSON

java - 尝试使用 JPA 删除数据库中的 2 行。一个对象是根据 id 创建的,但其他对象不是

java - "Failed to load ApplicationContext"使用@ContextConfiguration( "/applicationContext.xml") 和 Maven 结构