【问题标题】:Spring issues with configuration of JSON PrefixJSON 前缀配置的 Spring 问题
【发布时间】:2015-11-26 10:56:02
【问题描述】:

我正在配置我的 Spring 项目以添加 JSON 前缀 )]}',\n 以克服常见漏洞。我尝试按照this link 进行配置,它在启动服务器时导致异常。请帮我解决这个问题。

@Configuration
@EnableWebMvc
public Class WebAppConfig extends WebMvcConfigurationSupport
{
    public void addPrefixJSON()
    {
        List<HttpMessageConverter<?>> converters = super.getMessageConverters();
        MappingJackson2HttpMessageConverter convert = new MappingJackson2HttpMessageConverter();
        convert.setPrefixJson(true);
        converters.add(convert);
    }
}

我得到了以下异常,

08:01:23,435 ERROR [org.springframework.web.context.ContextLoader] 
(ServerService Thread Pool -- 68) Context initialization failed: 
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource 
[org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Instantiation of bean failed; nested exception is 
org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public 
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping 
org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.requestMappingHandlerMapping()] threw exception; nested exception is 
java.lang.ClassCastException: org.springframework.web.accept.ContentNegotiationManagerFactoryBean$$EnhancerByCGLIB$$6af53d42 cannot be cast to 
org.springframework.web.accept.ContentNegotiationManager

我在我的 spring-servlet.xml 中包含了&lt;mvc:annotation-driven /&gt; 我们是否有任何其他手动方法可以在旧版本的 Jackson 中添加前缀,比如 Jackson 1.6?

更新:

Jackson 2.0 解决了这个问题,我可以在浏览器中查看前缀,但是我看不到 angular end 的输出。

我的配置是这样的:

<mvc:annotation-driven content-negotiation-manager="contentManager">
            <mvc:message-converters>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                    <property name="jsonPrefix" value=")]}',\n" />
                </bean>
            </mvc:message-converters>
        </mvc:annotation-driven>

JSON 输出为

)]}',\n"{\"userName\":\"ABC\",\"emailId\":\"ABC@gmail.com\"}"

我对此输出感到困惑,此外 Angular 无法识别输出并且无法从该对象读取值。任何帮助都会非常有用。提前致谢。

【问题讨论】:

  • 此外,请帮助我了解如何在将其添加到 JSON 响应后验证此前缀。

标签: java json angularjs spring spring-mvc


【解决方案1】:

您可以XML encode 换行符以允许纯粹在 XML 中进行配置。

<mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="jsonPrefix" value=")]}',&#10;" />
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

【讨论】:

    【解决方案2】:

    我对这个输出感到困惑,除了 Angular 无法识别 输出并且无法从此对象读取值。任何帮助 会很棒的。

    问题与 Spring xml 配置有关:似乎某些字符已转义(可能 \n 已转义),因此如果您使用

    <mvc:annotation-driven content-negotiation-manager="contentManager">
                <mvc:message-converters>
                    <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                        <property name="jsonPrefix" value=")]}',\n" />
                    </bean>
                </mvc:message-converters>
            </mvc:annotation-driven>
    

    前缀是字符串 )]}',\n 而不是 )]}', + 新行。 所以我使用的一种解决方法是创建一个类(即 CustomMappingJackson2HttpMessageConverter),它扩展了原来的一个 org.springframework.http.converter.json.MappingJackson2HttpMessageConverter 并覆盖了 setJsonPrefix 方法,就像这样:

    public class CustomMappingJackson2HttpMessageConverter
            extends org.springframework.http.converter.json.MappingJackson2HttpMessageConverter {
    
        public CustomMappingJackson2HttpMessageConverter() {
            super();
        }
    
        public CustomMappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
            super(objectMapper);
        }
    
        @Override
        public void setJsonPrefix(String jsonPrefix) {
            super.setJsonPrefix(jsonPrefix+"\n");
        }   
    
    }
    

    我的配置是:

    <mvc:annotation-driven>
            <mvc:message-converters>
                 <bean class="mypackage.CustomMappingJackson2HttpMessageConverter">
                     <property name="jsonPrefix" value=")]}'," />
                 </bean>
             </mvc:message-converters>
        </mvc:annotation-driven>
    

    通过这种方式,您可以将配置保留在 xml 文件中,并允许 需要 2 行的正确 JSON 序列化/反序列化,第一个用于 )]}', 字符和 JSON 本身的第二个字符,这样 Angular 可以完美地工作

    一行JSON响应

    1 )]}',\n["id":1,"name":"Marco"....]
    

    两行 JSON 响应

    1 )]}',
    2 ["id":1,"name":"Marco"....]
    
    • AngularJS 版本。 1.5.9
    • Spring MVC 版本。 4.2.8

    希望对你有帮助

    【讨论】:

    • 使用 MappingJackson2HttpMessageConverter.setPrefixJson(true) 添加可能会默认写出所需的字符。
    【解决方案3】:

    Spring Lemon 中,简单地配置一个bean,如下所示,而不是上面的配置:

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setJsonPrefix(")]}',\n");
    
        return converter;
    }
    

    验证它是否正常工作的一种简单方法是查看响应数据,例如在 chrome 的 Network 标签中。

    【讨论】:

    • 我尝试在 spring-servlet.xml 中添加这个 bean 配置并检查 Chrome 中的响应。我看不到响应附加的前缀。对此有什么想法吗?
    • true这是我在 spring-servlet.xml 中的配置
    • 不要将prefixJson设置为true,我想你可以像我一样尝试一下,即将jsonPrefix设置为)]}',\n
    • 我试过这样做,但是在启动应用程序时我收到一条错误消息,指出 Bean property 'jsonPrefix' is not writable or has invalid setter method
    • 奇怪,似乎对我有用。我正在使用 Spring Boot 1.3.0.M3。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-10
    相关资源
    最近更新 更多