ehcache 生成空数据文件

ehcache generates empty data file

我想在我的 portlet 中使用带有 ehcache 的数据缓存。我使用 Spring MVC 和 liferay 门户。如果我想使用 Cacheable 注释,则会生成空数据文件。

SocialGraphUI-portlet.xml

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

   <context:component-scan base-package="socialgraphui" />

   <cache:annotation-driven />

   <cache:annotation-driven cache-manager="cacheManager" mode="proxy" proxy-target-class="true" />
   <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="/WEB-INF/ehcache.xml" p:shared="true" />
   <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehcache" />

   <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
      <property name="prefix" value="/WEB-INF/jsp/" />
      <property name="suffix" value=".jsp" />
      <property name="viewClass"
                  value="org.springframework.web.servlet.view.JstlView" />
   </bean>

   <mvc:annotation-driven>
    <mvc:message-converters>
        <bean class="org.springframework.http.converter.json.GsonHttpMessageConverter" />
    </mvc:message-converters>
    </mvc:annotation-driven>

    <bean class="org.springframework.web.portlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> 
    <bean class="org.springframework.web.portlet.mvc.annotation.DefaultAnnotationHandlerMapping"/> 

   <!-- Spring MVC Message Source -->
    <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
        <property name="useCodeAsDefaultMessage" value="true"/>
        <property name="basenames">
            <list>
                <value>content.socialGraph</value>
            </list>
        </property>
    </bean>

</beans>

ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <diskStore path="user.dir"/>
    <defaultCache eternal="true" overflowToDisk="true" diskPersistent="true" />
    <cache name="socialGraphCache" eternal="true" overflowToDisk="true" diskPersistent="true" />
</ehcache>

SocialGraphViewController.java

    package socialgraphui.controller;

    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import com.liferay.portal.kernel.util.ParamUtil;
    import socialgraphui.model.Edge;
    import socialgraphui.model.Message;
    import socialgraphui.model.Node;
    import socialgraphui.model.SocialGraph;
    import socialgraphui.service.SocialGraphService;
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.LinkedList;
    import java.util.List;
    import java.util.Locale;
    import org.apache.log4j.Logger;
    import javax.portlet.ActionRequest;
    import javax.portlet.ActionResponse;
    import javax.portlet.PortletSession;
    import javax.portlet.RenderRequest;
    import javax.portlet.RenderResponse;
    import javax.portlet.ResourceRequest;
    import javax.portlet.ResourceResponse;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Controller;
    import org.springframework.ui.ModelMap;
    import org.springframework.web.bind.WebDataBinder;
    import org.springframework.web.bind.annotation.InitBinder;
    import org.springframework.web.bind.annotation.ModelAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.portlet.bind.annotation.ActionMapping;
    import org.springframework.web.portlet.bind.annotation.RenderMapping;
    import org.springframework.web.portlet.bind.annotation.ResourceMapping;

    /**
     *
     * Controller for VIEW mode of portlet
     */
    @Controller("socialGraphViewController")
    @RequestMapping(value = "VIEW")
    public class SocialGraphViewController{

        Gson gson = new GsonBuilder().setPrettyPrinting().create();
        private static final Logger logger = Logger.getLogger(SocialGraphViewController.class);

        // -- auto-wiring of service dependency
        @Autowired
        @Qualifier("SGService")
        private SocialGraphService socialGraphService;

        public void setSocialGraphService(SocialGraphService service){
            this.socialGraphService = service;
        }

        @ModelAttribute(value="socialgraph")
        public SocialGraph getSocialGraph(){
            return socialGraphService.getSocialGraph();
        }

        @InitBinder
        public void initBinder(WebDataBinder binder) {
            binder.registerCustomEditor(PersonDefinitionTypeList.class, new PersonDefinitionTypeListEditor());
        }

        @ActionMapping(SocialGraphPortletConstants.SUBMIT_FILTER)
        public void handleActionRequest(ActionRequest request, ActionResponse response, PortletSession session)throws Exception {

            logger.info("handleActionRequest in was executed");

            ...
        }

@RenderMapping
    public String handleRenderRequest(RenderRequest request, RenderResponse response, ModelMap model, Locale locale, PortletSession session) {

      logger.info("handleRenderRequest was executed");

      ...

      return SocialGraphPortletConstants.VIEW;
   }

    }

我想缓存服务构造函数的结果,但不确定是否以正确的方式进行。

SocialGraphServiceImpl.java

import com.google.common.base.Function;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;
import com.google.common.collect.Sets;
import socialgraphui.controller.SocialGraphViewController;
import socialgraphui.model.Discussion;
import socialgraphui.model.Edge;
import socialgraphui.model.Email;
import socialgraphui.model.Message;
import socialgraphui.model.Node;
import socialgraphui.model.PhoneCall;
import socialgraphui.model.SocialGraph;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

/**
 *
 */
@Service(value="SGService")
public class SocialGraphServiceImpl implements SocialGraphService{

    private SocialGraph socialgraph = new SocialGraph();
    private CreateObjects crObjects = new CreateObjects();

    public SocialGraphServiceImpl(){
        this.fillGraph();
    }

    @Override
    @Cacheable(value = "socialGraphCache")
    public SocialGraph fillGraph(){
        this.socialgraph = crObjects.createObjects();
        return this.socialgraph;
    }
}

这是我要缓存的内容。

SocialGraph.java

package socialgraphui.model;

import java.io.Serializable;
import java.util.List;

public class SocialGraph implements Serializable{

    private static final long serialVersionUID = -6977846672304367384L;

    private List<Node> nodes;
    private List<Edge> edges;

    public List<Node> getNodes() {
        return nodes;
    }

    public void setNodes(List<Node> nodes) {
        this.nodes = nodes;
    }

    public List<Edge> getEdges() {
        return edges;
    }

    public void setEdges(List<Edge> edges) {
        this.edges = edges;
    }

}

当我部署 portlet 时,我没有收到任何错误,但生成的缓存文件是空的。

我有同样的问题,这是因为我没有实现我想保存在磁盘中的主要对象中使用的所有对象(class)。

有关详细信息,请参阅此示例。

  public class User implements Serializable{

       private Address address; // this object(class) not implements Serializable
   }

所以在为所有 class 实施后它可以正常工作。