【问题标题】:Jackson annotations being ignored in Spring杰克逊注释在春季被忽略
【发布时间】:2012-04-22 12:39:17
【问题描述】:

我正在尝试隐藏域类中的属性,但它一直出现在输出的 JSON 中。我正在使用 Jackson 2.0 和 Spring 3.1.1

/users/1 的输出:

{"id":1,"password":null,"email":"someone@somewhere.com","firstName":"John","lastName":"Smith"}

我的域类:

@Entity
public class User {
    private String mPassword;
    ... 
    @JsonIgnore
    public String getPassword() {
        return mPassword;
    }

    public void setPassword(String password) {
        mPassword = password;
    }
    ...
}

我的 springmvc 配置:

...
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
    <property name="favorPathExtension" value="true" />
    <property name="mediaTypes">
        <map>
            <entry key="json" value="application/json"/>
        </map>
    </property>
    <property name="defaultContentType" value="application/json"/>
    <property name="defaultViews">
        <list>
            <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" />
        </list>
    </property>
</bean>
...

还有我的控制器:

@Controller
@RequestMapping("/users")
public class UserController {
    private UserService mUserService;

    public UserController(){}

    @Inject
    public void setUserController(UserService userService){
        mUserService=userService;
    }

    @RequestMapping(value="/{id}", method=RequestMethod.GET)
    public void getUser(@PathVariable("id") long id, Model model){
        model.addAttribute(mUserService.getUser(id));
    }
}

【问题讨论】:

    标签: spring jackson


    【解决方案1】:

    Spring 3.1.2 添加了对 Jackson 2 的支持(从 Spring 3.2 向后移植 - SPR-9507)。只需将您的项目从 Spring 3.1.1 升级到 Spring 3.1.2,Jackson 2 就可以使用您已有的配置。

    【讨论】:

      【解决方案2】:

      问题在于 Spring 不适用于 Jackson 2.0。这已通过以下方式解决:

      <bean id="jacksonMessageConverter"
                class="own.implementation.of.MappingJacksonHttpMessageConverter"/>
      
      <bean class="org.springframework.web.servlet.mvc
                   .annotation.AnnotationMethodHandlerAdapter">
              <property name="messageConverters">
                  <list>
                      <ref bean="jacksonMessageConverter"/>
                  </list>
              </property>
              <property name="requireSession" value="false"/>
          </bean>
      

      而own.implementation.of.MappingJacksonHttpMessageConverter就是基于这个:

      http://www.jarvana.com/jarvana/view/org/springframework/spring-web/3.0.0.RELEASE/spring-web-3.0.0.RELEASE-sources.jar!/org/springframework/http/converter/json/MappingJacksonHttpMessageConverter.java?format=ok

      但是使用 ObjectMapper 和 Jackson 2.0 中的其他 Jackson 类而不是 Jackson 1.*

      【讨论】:

      • 我想我会降级到 Jackson 1.9,这似乎可以解决我的问题。
      • 除非您需要 2.0 的功能(例如传递具有双向关系的对象)。这就是我升级到 2.0 的原因。
      【解决方案3】:

      除了升级到Spring 3.1.2,还得把消息转换器改成org.springframework.web.servlet.view.json.MappingJackson**2**HttpMessageConverter

      【讨论】:

        【解决方案4】:

        如果您使用的是 Spring 4 版本,则必须执行以下操作,更新依赖项

        <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-core</artifactId>
                <version>2.3.3</version>
            </dependency>
        
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.3.3</version>
        </dependency>
        

        将旧的 codehaus 注释导入替换为以下,如果不这样做,您的旧注释(如 JsonIgnoreProperties)将无法与新版本的 Jackson 一起使用

        import com.fasterxml.jackson.annotation.*;
        

        从下面删除 mediaTypes,它已被弃用。

        ContentNegotiatingViewResolver

        ,不需要,将从激活框架jar中提取,Jackson视图应该使用

        映射Jackson2JsonView

        <beans:property name="viewResolvers">
            <beans:list>
                <beans:bean
                    class="org.springframework.web.servlet.view.BeanNameViewResolver" />
                <beans:bean
                    class="org.springframework.web.servlet.view.InternalResourceViewResolver">
                    <beans:property name="prefix" value="/WEB-INF/views/" />
                    <beans:property name="suffix" value=".jsp" />
                </beans:bean>
                <beans:bean
                    class="org.springframework.web.servlet.view.tiles3.TilesViewResolver">
                    <beans:property name="viewClass"
                        value="org.springframework.web.servlet.view.tiles3.TilesView"></beans:property>
                    <beans:property name="order" value="0"></beans:property>
                </beans:bean>
            </beans:list>
        </beans:property>
        <beans:property name="defaultViews">
            <beans:list>
                <beans:bean
                    class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
            </beans:list>
        </beans:property>
        

        【讨论】:

          【解决方案5】:

          我的配置是这样的

          <bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order="1">
            <property name="mediaTypes">
              <map>
                <entry key="html" value="text/html"/>
                <entry key="json" value="application/json"/>
              </map>
             </property>
            <property name="viewResolvers">
              <!-- this is not important for your jackson problem -->
              <bean id="tilesViewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver" p:viewClass="org.springframework.web.servlet.view.tiles2.TilesView" p:order="2" depends-on="tilesConfigurer"/>
            </property>
            <property name="defaultViews">
              <list>
                <bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>
              </list>
            </property>
          </bean>
          

          我的控制器是这样的

          @Controller
          public class SearchController {
             @RequestMapping(value="/search", method = {RequestMethod.GET, RequestMethod.POST})
             public SearchResponse search(@RequestParam(value = QUERY, required = true) String query) {
                 return generateSearchResponse(query);
             }
          }    
          

          我的 SearchResponse 结构更复杂,但它包含这种类型的对象。

          @JsonIgnoreProperties({ "popis" })
          public class Kurz implements Serializable {
              private String nazev;
              private String popis;
          }
          

          【讨论】:

          • 添加属性似乎没有任何区别,可能不是必需的。
          • 尝试在字段上放置忽略注释而不是 getter。我认为杰克逊默认读取并直接设置表单字段。
          • 恐怕这行不通。我不认为它在使用 Jackson - 它能够在没有 Jackson jar 可用的情况下序列化 JSON。此外,我不应该将 @ResponseBody 与 ContentNegotiatingViewResolver 一起使用,而是应该返回视图“json”或使用 HttpMessageConverter。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-05-18
          • 1970-01-01
          • 2016-01-16
          • 2016-08-07
          • 2011-10-22
          • 1970-01-01
          相关资源
          最近更新 更多