基於Spring4.X和Hibernate4.x開發Restful風格WebService

    個人開發IDE爲eclipse並且我web項目採用集成maven,因此若是你對maven不是太瞭解能夠先查詢一下資料瞭解一下maven。前端

    1.環境搭建
java

    這是個人POM文件,包括所依賴的jar包和一些經常使用的插件web

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>SafetyMonitorService</groupId>
    <artifactId>SafetyMonitorService</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>SafetyMonitorService Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>4.2.5.RELEASE</spring.version>
        <hibernate.version>4.3.6.Final</hibernate.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.deploy>AppVersionManagement</project.deploy>
        <project.tomcat.version>8.0.28</project.tomcat.version>
    </properties>

    <dependencies>
        <!-- junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <!-- Servlet -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>
            <scope>provided</scope>
        </dependency>
        <!-- javax.ws.rs -->
        <dependency>
            <groupId>javax.ws.rs</groupId>
            <artifactId>javax.ws.rs-api</artifactId>
            <version>2.0.1</version>
        </dependency>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.14</version>
        </dependency>
        <!-- hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <!-- transaction-jta -->
        <dependency>
            <groupId>javax.transaction</groupId>
            <artifactId>jta</artifactId>
            <version>1.1</version>
        </dependency>
        <!-- fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.8</version>
        </dependency>
        <!-- druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.17</version>
        </dependency>
        <!-- SQLServer-jtds -->
        <dependency>
            <groupId>net.sourceforge.jtds</groupId>
            <artifactId>jtds</artifactId>
            <version>1.2</version>
        </dependency>
        <!-- hibernate -->
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>${hibernate.version}</version>
        </dependency>
        <!-- memcached -->
        <dependency>
            <groupId>com.danga</groupId>
            <artifactId>java-memcached</artifactId>
            <version>2.6.2</version>
        </dependency>
        <dependency>
            <groupId>net.spy</groupId>
            <artifactId>spymemcached</artifactId>
            <version>2.12.0</version>
        </dependency>
        <dependency>
            <groupId>fakepath</groupId>
            <artifactId>hibernate-memcached</artifactId>
            <version>1.5</version>
        </dependency>
        <!-- Jackson JSON -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.6.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.6.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>2.6.4</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>SafetyMonitorService</finalName>
        <plugins>
            <!-- Apache官方TomcatPlugin 遠程部署 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <url>http://111.175.187.206:5007/manager/text</url>
                    <username>admin</username>
                    <password>admin</password>
                    <path>/${project.deploy}</path>
                </configuration>
            </plugin>
            <!-- Apache官方TomcatPlugin 本地部署 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>5008</port>
                    <path>/${project.deploy}</path>
                    <uriEncoding>${project.build.sourceEncoding}</uriEncoding>
                    <finalName>${project.deploy}</finalName>
                    <server>tomcat7</server>
                </configuration>
            </plugin>
            <!-- Compile Plugin -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.3</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>${project.build.sourceEncoding}</encoding>
                </configuration>
            </plugin>
            <!-- Jetty Plugin -->
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>maven-jetty-plugin</artifactId>
                <version>6.1.26</version>
                <configuration>
                    <webAppSourceDirectory>${basedir}/src/main/webapp</webAppSourceDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

    2.從POJO開始說ajax

    個人pojo結構以下算法

    很明顯個人pojo包下面分爲了3個子包分別爲dto、po和vo,那有人可能就會問了,他們都是什麼意思而且分別都表明什麼功能?那我就來給大家分享個人認知經驗。首先dto是傳輸對象,構造這個對象主要是最終傳遞給調用者的對象。po毋庸置疑是屬於數據庫映射出來的對象,這裏面能夠看到只有單單的類文件,沒有.hbm映射文件。緣由是個人po實體類上面都加有JPA註解,其實效果和.hbm文件達到的效果是同樣的,這個經過hibernate的反向工程能夠獲得。不太會生成po這些類的話,百度一下幫你解決。而後是vo包下面類存在的緣由,這個是我用來傳輸的對象。主要是解決dao層查詢出來的存在one to many 或者 many to one 關聯致使Json序列化出現死循環的問題,可在Service將查詢出來的po對象賦值給vo對象從而傳遞給調用者。dto包下的request爲傳入對象,response爲返回的對象,ResponsePaging則爲分頁的返回對象。spring

    3.Dao和Service
數據庫

    和不少web項目同樣,個人Dao結構和Service結構相似,都包含公共接口和公共抽象類以及具體的對象接口以及對應的實現類。這裏只列舉Dao的結構,Service與之相似。apache

    公共接口:基本包含了全部的操做方法
編程

package com.evt.charge.rpc.dao;

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

import com.evt.charge.rpc.pojo.dto.Request;

public interface ICommonDao<T extends Serializable> {
    T findOne(final long id);
    
    T findOne(final int id);
    
    T findOne(final String id);

    List<T> findAll(Request resquest);
    
    List<T> findAll();

    void save(final T entity);
    
    void saveOrUpdate(final T entity);
    
    void batchSave(final List<T> entities);

    T update(final T entity);

    void delete(final T entity);

    void deleteById(final int entityId);
    
    void deleteById(final long entityId);
    
    void deleteById(final String entityId);
}

    公共抽象類:實現了公共接口的全部的方法而且有sessionFactory注入以及Class對象的設置。值得注意的是我獲取session經過sessionFactory.getCurrentSession()方法得到,沒有調用openSession()方法。這樣的好處是將session的管理交給spring容器,這樣再也不須要每次獲取session都須要從新重鏈接池那一條鏈接致使服務器鏈接池濫用,也再也不須要手動關閉session,鏈接關閉以前自動提交事務關閉session。json

package com.evt.charge.rpc.dao;

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

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.evt.charge.rpc.exception.DaoException;
import com.evt.charge.rpc.exception.ExceptionCode;
import com.evt.charge.rpc.pojo.dto.Request;

@SuppressWarnings("unchecked")
public abstract class AbstractBaseDao<T extends Serializable> implements
        ICommonDao<T> {

    private Class<T> clazz;

    @Resource(name = "sessionFactory")
    private SessionFactory sessionFactory;

    protected final void setClazz(final Class<T> clazzToSet) {
        this.clazz = clazzToSet;
    }

    protected final Session getSession() {
        return sessionFactory.getCurrentSession();
    }

    @Override
    public final T findOne(final long id) {
        return (T) getSession().get(clazz, id);
    }

    @Override
    public final T findOne(final int id) {
        return (T) getSession().get(clazz, id);
    }

    @Override
    public final T findOne(final String id) {
        return (T) getSession().get(clazz, id);
    }

    @Override
    public final List<T> findAll(Request resquest) {
        int pageIndex = resquest.getPageIndex();
        int pageSize = resquest.getPageSize();
        String orderParam = resquest.getOrderbyParam();
        StringBuffer hql = new StringBuffer("from " + clazz.getName());
        if (resquest.getOrder() == 0 && orderParam != null) {
            hql.append(" order by " + orderParam + " asc");
        } else if (resquest.getOrder() == 1 && orderParam != null) {
            hql.append(" order by " + orderParam + " desc");
        }
        Query query = getSession().createQuery(hql.toString());
        query.setFirstResult((pageIndex - 1) * pageSize);
        query.setMaxResults(pageSize);
        query.setCacheable(true);
        return query.list();
    }

    @Override
    public final List<T> findAll() {
        Query query = getSession().createQuery("from " + clazz.getName());
        query.setCacheable(true);
        return query.list();
    }

    @Override
    public final void save(final T entity) {
        Session session = getSession();
        session.save(entity);
    }

    @Override
    public final void saveOrUpdate(final T entity) {
        Session session = getSession();
        session.saveOrUpdate(entity);
    }

    @Override
    public final void batchSave(final List<T> entities) {
    }

    @Override
    public final T update(final T entity) {
        Session session = getSession();
        session.update(entity);
        return entity;
    }

    @Override
    public final void delete(final T entity) {
        Session session = getSession();
        session.delete(entity);
    }

    @Override
    public final void deleteById(final long entityId) {
        final T entity = findOne(entityId);
        delete(entity);
    }

    @Override
    public final void deleteById(final int entityId) {
        final T entity = findOne(entityId);
        delete(entity);
    }

    @Override
    public final void deleteById(final String entityId) {
        final T entity = findOne(entityId);
        delete(entity);
    }

    protected void closure(Session session) {
        if (session != null) {
            session.flush();
            session.clear();
            session.close();
        }
    }
}

    4.控制器

    一樣是基於註解的配置,@RestController是Spring4.0的新註解,是由@Controller和@ResponseBody(實現返回對象序列化)組成@RequestMapping裏面的請求方法只能選擇一種,value是請求的地址。@RequestBody是Http請求的請求體,我採用的是經過傳入json字符串來傳參。

package com.evt.app.rest.controller;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.PathParam;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;

import com.alibaba.fastjson.JSON;
import com.evt.app.rest.pojo.Response;
import com.evt.app.rest.service.IAppVersionRecordService;
import com.evt.app.rest.util.DeleteFileUtil;
import com.evt.app.rest.util.UploadFileUtil;

@RestController
public class AppVersionController {

    @Autowired
    private IAppVersionRecordService appVersionRecordService;
    
    /**
     * 獲取全部版本信息
     * 
     * @return
     */
    @RequestMapping(value = "/getAppVersion", method = RequestMethod.POST)
    public Response getAppVersion() {
        return appVersionRecordService.getAppVersion();
    }

    /**
     * 增長或修改版本信息
     * 
     * @param param
     */
    @RequestMapping(value = "/saveOrUpdateAppVersion", method = RequestMethod.POST)
    public void saveOrUpdateAppVersion(@RequestBody String param) {
        appVersionRecordService.saveOrUpdateAppVersion(param);
    }

    /**
     * 刪除版本信息
     * 
     * @param param
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/deleteAppVersion", method = RequestMethod.POST)
    public void deleteAppVersion(@RequestBody String param) {
        Map<String, String> map = JSON.parseObject(param, Map.class);
        int id = Integer.valueOf(map.get("id"));
        appVersionRecordService.deleteById(id);
    }

    /**
     * findById版本信息
     * 
     * @param param
     * @return
     */
    @RequestMapping(value = "/findAppVersionOne/{param}", method = RequestMethod.POST)
    public Response findAppVersionOne(@PathVariable("param") @RequestBody String param) {
        return appVersionRecordService.findAppVersionOne(param);
    }
}

   5.其餘細節

    異常處理:

    在 Spring MVC 中,咱們可使用 AOP 技術,編寫一個全局的異常處理切面類,用它來統一處理全部的異常行爲,在 Spring 3.2 中才開始提供。使用法很簡單,只需定義一個類,並經過 @ControllerAdvice 註解將其標註便可,同時須要使用 @ResponseBody 註解表示返回值可序列化爲 JSON 字符串。代碼以下:

@ControllerAdvice@ResponseBodypublic class ExceptionAdvice {    /**
     * 400 - Bad Request
     */
    @ResponseStatus(HttpStatus.BAD_REQUEST)    @ExceptionHandler(HttpMessageNotReadableException.class)    public Response handleHttpMessageNotReadableException(HttpMessageNotReadableException e) {
        logger.error("參數解析失敗", e);        return new Response().failure("could_not_read_json");
    }    /**
     * 405 - Method Not Allowed
     */
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)    @ExceptionHandler(HttpRequestMethodNotSupportedException.class)    public Response handleHttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        logger.error("不支持當前請求方法", e);        return new Response().failure("request_method_not_supported");
    }    /**
     * 415 - Unsupported Media Type
     */
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)    @ExceptionHandler(HttpMediaTypeNotSupportedException.class)    public Response handleHttpMediaTypeNotSupportedException(Exception e) {
        logger.error("不支持當前媒體類型", e);        return new Response().failure("content_type_not_supported");
    }    /**
     * 500 - Internal Server Error
     */
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)    @ExceptionHandler(Exception.class)    public Response handleException(Exception e) {
        logger.error("服務運行異常", e);        return new Response().failure(e.getMessage());
    }
}

    可見,在 ExceptionAdvice 類中包含一系列的異常處理方法,每一個方法都經過 @ResponseStatus 註解定義了響應狀態碼,此外還經過 @ExceptionHandler 註解指定了具體須要攔截的異常類。以上過程只是包含了一部分的異常狀況,若需處理其它異常,可添加方法具體的方法。須要注意的是,在運行時從上往下依次調 用每一個異常處理方法,匹配當前異常類型是否與 @ExceptionHandler 註解所定義的異常相匹配,若匹配,則執行該方法,同時忽略後續全部的異常處理方法,最終會返回經 JSON 序列化後的 Response 對象。

    解決跨域問題

    好比,前端應用爲靜態站點且部署在 http://web.xxx.com 域下,後端應用發佈 REST API 並部署在 http://api.xxx.com 域下,如何使前端應用經過 AJAX 跨域訪問後端應用呢?這須要使用到 CORS 技術來實現,這也是目前最好的解決方案了。

CORS 全稱爲 Cross Origin Resource Sharing(跨域資源共享),服務端只需添加相關響應頭信息,便可實現客戶端發出 AJAX 跨域請求。

    CORS 技術很是簡單,易於實現,目前絕大多數瀏覽器均已支持該技術(IE8 瀏覽器也支持了),服務端可經過任何編程語言來實現,只要能將 CORS 響應頭寫入 response 對象中便可。

下面咱們繼續擴展 REST 框架,經過 CORS 技術實現 AJAX 跨域訪問。

首先,咱們須要編寫一個 Filter,用於過濾全部的 HTTP 請求,並將 CORS 響應頭寫入 response 對象中,代碼以下:

public class CorsFilter implements Filter {    private String allowOrigin;    private String allowMethods;    private String allowCredentials;    private String allowHeaders;    private String exposeHeaders;    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        allowOrigin = filterConfig.getInitParameter("allowOrigin");
        allowMethods = filterConfig.getInitParameter("allowMethods");
        allowCredentials = filterConfig.getInitParameter("allowCredentials");
        allowHeaders = filterConfig.getInitParameter("allowHeaders");
        exposeHeaders = filterConfig.getInitParameter("exposeHeaders");
    }    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;        if (StringUtil.isNotEmpty(allowOrigin)) {
            List<String> allowOriginList = Arrays.asList(allowOrigin.split(","));            if (CollectionUtil.isNotEmpty(allowOriginList)) {
                String currentOrigin = request.getHeader("Origin");                if (allowOriginList.contains(currentOrigin)) {
                    response.setHeader("Access-Control-Allow-Origin", currentOrigin);
                }
            }
        }        if (StringUtil.isNotEmpty(allowMethods)) {
            response.setHeader("Access-Control-Allow-Methods", allowMethods);
        }        if (StringUtil.isNotEmpty(allowCredentials)) {
            response.setHeader("Access-Control-Allow-Credentials", allowCredentials);
        }        if (StringUtil.isNotEmpty(allowHeaders)) {
            response.setHeader("Access-Control-Allow-Headers", allowHeaders);
        }        if (StringUtil.isNotEmpty(exposeHeaders)) {
            response.setHeader("Access-Control-Expose-Headers", exposeHeaders);
        }
        chain.doFilter(req, res);
    }    @Override
    public void destroy() {
    }
}

    以上 CorsFilter 將從 web.xml 中讀取相關 Filter 初始化參數,並將在處理 HTTP 請求時將這些參數寫入對應的 CORS 響應頭中,下面大體描述一下這些 CORS 響應頭的意義:

  • Access-Control-Allow-Origin:容許訪問的客戶端域名,例如:http://web.xxx.com,若爲 *,則表示從任意域都能訪問,即不作任何限制。

  • Access-Control-Allow-Methods:容許訪問的方法名,多個方法名用逗號分割,例如:GET,POST,PUT,DELETE,OPTIONS。

  • Access-Control-Allow-Credentials:是否容許請求帶有驗證信息,若要獲取客戶端域下的 cookie 時,須要將其設置爲 true。

  • Access-Control-Allow-Headers:容許服務端訪問的客戶端請求頭,多個請求頭用逗號分割,例如:Content-Type。

  • Access-Control-Expose-Headers:容許客戶端訪問的服務端響應頭,多個響應頭用逗號分割。

    須要注意的是,CORS 規範中定義 Access-Control-Allow-Origin 只容許兩種取值,要麼爲 *,要麼爲具體的域名,也就是說,不支持同時配置多個域名。爲了解決跨多個域的問題,須要在代碼中作一些處理,這裏將 Filter 初始化參數做爲一個域名的集合(用逗號分隔),只需從當前請求中獲取 Origin 請求頭,就知道是從哪一個域中發出的請求,若該請求在以上容許的域名集合中,則將其放入 Access-Control-Allow-Origin 響應頭,這樣跨多個域的問題就輕鬆解決了。

如下是 web.xml 中配置 CorsFilter 的方法:

<filter>
    <filter-name>corsFilter</filter-name>
    <filter-class>com.xxx.api.cors.CorsFilter</filter-class>
    <init-param>
        <param-name>allowOrigin</param-name>
        <param-value>http://web.xxx.com</param-value>
    </init-param>
    <init-param>
        <param-name>allowMethods</param-name>
        <param-value>GET,POST,PUT,DELETE,OPTIONS</param-value>
    </init-param>
    <init-param>
        <param-name>allowCredentials</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>allowHeaders</param-name>
        <param-value>Content-Type</param-value>
    </init-param></filter><filter-mapping>
    <filter-name>corsFilter</filter-name>
    <url-pattern>/*</url-pattern></filter-mapping>

    完成以上過程便可實現 AJAX 跨域功能了,但彷佛還存在另一個問題,因爲 REST 是無狀態的,後端應用發佈的 REST API 可在用戶未登陸的狀況下被任意調用,這顯然是不安全的,如何解決這個問題呢?咱們須要爲 REST 請求提供安全機制。

配置緩存服務器

    爲了更加高效的經過查詢獲取個人WebService接口服務我在個人WebService中加入的Memcached緩存的支持,在Habernate中加入以下配置:

        <!-- 開啓二級緩存 -->
        <property name="hibernate.cache.use_second_level_cache">true</property>
        <!-- 開啓查詢緩存 -->
        <property name="hibernate.cache.use_query_cache">true</property>
        <!-- 結構化查詢 -->
        <property name="hibernate.cache.use_structured_entries">true</property>
        <!-- 緩存提供商 -->
        <property name="hibernate.cache.region.factory_class">com.googlecode.hibernate.memcached.MemcachedRegionFactory</property>
        <!-- memcached 服務地址,多個用空格分隔格式host:port -->
        <property name="hibernate.memcached.servers">192.168.1.194:11211,192.168.1.223:11211</property>
        <!-- 區域前綴 -->
        <property name="hibernate.cache.region_prefix">quality.cache.memcached</property>
        <!-- 設置鏈接工廠 -->
        <property name="hibernate.memcached.connectionFactory">KetamaConnectionFactory</property>
        <!-- 緩存失效時間,單位秒 -->
        <property name="hibernate.memcached.cacheTimeSeconds">300</property>
        <!-- 緩存Key生成存儲HashCode算法 -->
        <property name="hibernate.memcached.keyStrategy">HashCodeKeyStrategy</property>
        <!-- 屬性配置 -->
        <property name="hibernate.memcached.readBufferSize">16384</property>
        <property name="hibernate.memcached.operationQueueLength">16384</property>
        <property name="hibernate.memcached.operationTimeout">2500</property>
        <property name="hibernate.memcached.hashAlgorithm">NATIVE_HASH</property>
        <property name=" hibernate.memcached.clearSupported">false</property>

    在vo實體類上加上@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)配置以下:



6.總結

    經過本次基於Spring和Hibernate對於Restful風格的WebService的開發,發現基於此實現的WebService比較輕量級並且實現起來很是的簡單。支持前端頁面的ajax調用,對於面向服務的比較複雜的SAOP式的WebService來講在不少時候都是很是輕便而高效的。

相關文章
相關標籤/搜索