1. 程式人生 > >解決使用fastJson中出現$ref問題(我用了配置的方法,好用)

解決使用fastJson中出現$ref問題(我用了配置的方法,好用)

首先:
部門與組織是manytoone和onetomany的關係,並且兩張表都有自關聯,查詢部門資訊時會級聯查詢上級部門以及他的組織結構,然後返回json資料時,會出現$ref
即:
這裡寫圖片描述
為了攻破它,在兩張表的onetomany那方,也就是set的那方,加一個fastjson的註解@JSONField(serialize = false)
即:
這裡寫圖片描述
由於我組織結構那裡有多個onetomany,所以我都加上了:

這裡寫圖片描述
然後在controller裡面有兩種寫法:
一:在方法前面加 @ResponseBody,再直接返回一個物件

 /**

 * 部門資訊列表展示
 * @param response
 */
@ResponseBody
@RequestMapping(value = "/list", method = RequestMethod.GET)
public PageView<Department> list(HttpServletResponse response, Integer pageSize, Integer page) {
    PageView<Department> departmentPageView = departmentService.queryBySerach(null, page, pageSize);
    //ajaxJson(JSON.toJSONString(departmentPageView, SerializerFeature.DisableCircularReferenceDetect), response);
    return departmentPageView;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

然後在配置檔案裡配置:

<mvc:annotation-driven>
   <mvc:message-converters register-defaults="true">
      <bean id="fastJsonHttpMessageConverter" class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
         <property name="supportedMediaTypes">
            <list>
               <value>application/json;charset=UTF-8</value>
            </list>
         </property>
         <property name="features">
            <array>
               <value>DisableCircularReferenceDetect</value>
            </array>
         </property>
      </bean>
   </mvc:message-converters>
</mvc:annotation-driven>
<bean id="DisableCircularReferenceDetect" class="org.springframework.beans.factory.config.FieldRetrievingFactoryBean">
   <property name="staticField" value="com.alibaba.fastjson.serializer.SerializerFeature.DisableCircularReferenceDetect"></property>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在使用Spring注入時,我們將類資訊注入到com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter
這個類中。
在原始碼中可以看到:

@Override
    protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException,
                                                                             HttpMessageNotWritableException {

        OutputStream out = outputMessage.getBody();
        String text = JSON.toJSONString(obj, features);
        byte[] bytes = text.getBytes(charset);
        out.write(bytes);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

我們使用@ResponseBody這個註解時,會自動呼叫JSON.toJSONString(obj,features)這個方法,裡面會帶上我們在Spring裡面配置的屬性。
附一種不好的程式設計習慣:
在加了@ResponseBody註解的Controller中使用

String result = JSON.toJSONString(obj);
return result;
  • 1
  • 2

JSON.toJSONString() 這句話執行了兩次。

方案二:不用配置檔案,直接轉SerializerFeature.DisableCircularReferenceDetect
即:

/**
 * 部門資訊列表展示
 * @param response
 */

@RequestMapping(value = "/list", method = RequestMethod.GET)
public void list(HttpServletResponse response, Integer pageSize, Integer page) {
    PageView<Department> departmentPageView = departmentService.queryBySerach(null, page, pageSize);
    ajaxJson(JSON.toJSONString(departmentPageView, SerializerFeature.DisableCircularReferenceDetect,SerializerFeature.WriteMapNullValue), response);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

然後ajaxJson方法是:

@Controller
public class BaseController
{
   protected static final Log log = LogFactory.getLog(BaseController.class);

   /** ajax輸出,返回null ***/
   public String ajax(String content, String type, HttpServletResponse response)
   {
      try
      {
         response.setContentType(type + ";charset=UTF-8");
         response.setHeader("Pragma", "No-cache");
         response.setHeader("Cache-Control", "no-cache");
         response.setDateHeader("Expires", 0);
         response.getWriter().write(content);
         response.getWriter().flush();
      }
      catch (IOException e)
      {
         log.error("ajax", e);
      }
      return null;
   }