干货--Redis+Spring+Struts2实现网站计算器应用项目案例

有关redis的介绍我就不说了,可以参看我前几篇文章,redis快速入门 首先来看一下redis的应用场景

这里写图片描述

下面是我这个项目的的运行的场景截图

这里写图片描述

这是我们经常在各博客见到的顶和踩的画面,对于这种场景,我们用非关系型数据库来操作是非常不方便地,不光是查询不方便(写sql语句),而且在高并发的时候,可能会使系统假死,所以redis就派上用场了,它属于非关系型数据库,它直接操作内存,非常快速。 下面直接看代码 首先看看所需的包 除了Spring和Struts2所需的包外 还需连接redis的包 这里是spring-data-redis

这里写图片描述
这里写图片描述

本项目是模拟用户实现顶和踩的功能

所以先创一个实体类User

代码语言:javascript
复制
package com.yc.beans;

public class User {
private int ding;//顶
private int cai;//踩

public int getCai() {
    return cai;
}

public void setCai(int cai) {
    this.cai = cai;
}

public int getDing() {
    return ding;
}

public void setDing(int ding) {
    this.ding = ding;
}

}

因为是spring+Struts2一起,所以要改web.xml配置文件

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:web="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" id="WebApp_9" version="2.4">

<!-- spring的配置文件的路径, -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext*.xml</param-value>
</context-param>
<!-- 配置spring的上下文临听器: 当应用程序一加载到服务器上时,就会调用这个 ContextLoaderListerner, 这个临听器会读取contextConfigLocation配置的spring配置文件,完成
spring容器的初始化.

 --&gt;

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- struts2的前端过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

首先看一下客户端请求页面 index.jsp

代码语言:javascript
复制
<%@ page
language="java"
contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta
http-equiv="Content-Type"
content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style>
#head {
font-family: cursive;
font-size: 25px;
color: orange;
cursor: pointer;
}

#content {height =300px;
font-family: cursive;
font-size: 20px;
}

.ding {
border: 1px solid blue;
height: 60px;
width: 70px;
margin-left: 150px; padding-left10px;
float: left;
background: #FFF;
}

.ding img {
display: inline-block;
margin-top: 15px;
margin-left: 10px;
cursor: pointer;
}

.sding {
float: left;
margin-top: 16px;
font-family: cursive;
text-decoration: underline;
}
</style>
<script src="js/jquery-1.11.3.js"></script>
<script type="text/javascript">
//当这个页面加载完毕 则给 loginbtn绑定单击事件
$(function() {
$.ajax({
type : "POST",
url : "User_Find.action",
dataType : 'JSON',
success : function(data) {
if (data.code == 1) {
$("#num").text(data.obj.ding);
$("#numcai").text(data.obj.cai);
} else {
alert(data);
}
}

    });
});
function addDing() {

    $.ajax({
        type : &#34;POST&#34;,
        url : &#34;User_Ding.action&#34;,
        dataType : &#39;JSON&#39;,
        success : function(data) {
            if (data.code == 1) {
                $(&#34;#num&#34;).text(data.obj.ding)
            } else {
                alert(data);
            }
        }

    });
}

function addCai(){
$.ajax({
type:"POST",
url:"User_Cai.action",
dataType:'JSON',
success: function(data){
if(data.code==1){
$("#numcai").text(data.obj.cai);
}else{
alert(data);
}
}

    });
}

</script>
</head>

<body>
<center>
<div style="background: #0F0; height: 400px; width: 600px;">
<table
CELLPADDING="0"
border="1px"
bordercolor="yellow"
height="400px"
width="600px">
<tr>
<th
id="head"
align="left"
height="50px"
colspan="3">年度最热门博客</th>
</tr>
<tr id="content">

                &lt;td
                    height=&#34;200&#34;
                    colspan=&#34;3&#34;&gt;都说飞得越高,摔得越惨,但是我想看看我到底会摔得有多惨,落地了,只要没死,那么爬起来,每走一步都是向上! &lt;br&gt;
                    &lt;/br&gt;
                    时间并不会真的帮我们解决什么问题,它只是把原来怎么也想不通的问题,变得不再重要了。
                    &lt;/td&gt;
            &lt;/tr&gt;
            &lt;tr&gt;
                &lt;td colspan=&#34;3&#34;&gt;
                    &lt;div class=&#34;ding&#34;&gt;
                        &lt;span class=&#34;sding&#34;&gt;顶&lt;/span&gt;&lt;img
                            alt=&#34;tup&#34;
                            src=&#34;images/ding.gif&#34;
                            onclick=&#34;addDing()&#34;&gt;&lt;span id=&#34;num&#34;&gt;&lt;/span&gt;
                    &lt;/div&gt;
                    &lt;div class=&#34;ding&#34;&gt;
                        &lt;span class=&#34;sding&#34;&gt;踩&lt;/span&gt;&lt;img
                            alt=&#34;tup&#34;
                            src=&#34;images/cai.gif&#34; onclick=&#34;addCai()&#34;&gt;&lt;span id=&#34;numcai&#34;&gt;&lt;/span&gt;
                    &lt;/div&gt;
                &lt;/td&gt;
            &lt;/tr&gt;
        &lt;/table&gt;
    &lt;/div&gt;
&lt;/center&gt;

</body>

</html>

它发请求到UserAction,请后台传递数据用JSON
所以再看看Struts.xml,

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
<!-- 关闭动态方法调用 actionid!方法名.action -->
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<!-- 启用开发模式 -->
<constant name="struts.devMode" value="true" />
<!-- action的创建由spring来完成,而不由struts完成. -->
<constant name="struts.objectFactory" value="spring" />

&lt;package name=&#34;default&#34; namespace=&#34;/&#34; extends=&#34;json-default&#34;&gt;

  &lt;action name=&#34;User_*&#34; class=&#34;userAction&#34; method=&#34;{1}&#34;&gt;
    &lt;result name=&#34;success&#34; type=&#34;json&#34;&gt;
            &lt;param name=&#34;root&#34;&gt;
                jsonModel
            &lt;/param&gt;
        &lt;/result&gt;
  &lt;/action&gt;
&lt;/package&gt;

</struts>

再看UserAction之前,我们先看看一个帮助类

代码语言:javascript
复制
package com.yc.utils;
import java.io.Serializable;
public class JsonModel implements Serializable {
/**
*
*/
private static final long serialVersionUID = -7830500053112045585L;
private Integer code;
private String message;
private Object obj;
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}

}

通过这个帮助类将数据转为JSON数据发给前台,具体看后面的代码

我们连接redis服务都是通过spring来完成的,所以我们看看spring 的配置文件

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

&lt;!-- 启用注解解析器 --&gt;
&lt;context:annotation-config /&gt;
&lt;!-- 因为采用了混合解析方式( 有一部分配置在xml中,有一部分在java类中,所以要让spring的注解解析器去扫描包 --&gt;
&lt;context:component-scan base-package=&#34;com.yc&#34; /&gt;
&lt;!-- 启用aspectj的注解方式的代理 --&gt;
&lt;aop:aspectj-autoproxy /&gt;

&lt;!-- 创建redis工厂 --&gt;
&lt;bean id=&#34;jedisFactory&#34;
    class=&#34;org.springframework.data.redis.connection.jedis.JedisConnectionFactory&#34;&gt;
    &lt;property name=&#34;hostName&#34; value=&#34;localhost&#34; /&gt;
    &lt;property name=&#34;port&#34; value=&#34;6379&#34; /&gt;
    &lt;property name=&#34;usePool&#34; value=&#34;true&#34; /&gt;
&lt;/bean&gt;

&lt;bean id=&#34;redisTemplate&#34; class=&#34;org.springframework.data.redis.core.RedisTemplate&#34;&gt;
    &lt;property name=&#34;connectionFactory&#34; ref=&#34;jedisFactory&#34; /&gt;
    &lt;property name=&#34;keySerializer&#34;&gt;  
        &lt;bean  
            class=&#34;org.springframework.data.redis.serializer.StringRedisSerializer&#34; /&gt;  
    &lt;/property&gt;  
    &lt;property name=&#34;valueSerializer&#34;&gt;  
        &lt;bean  
            class=&#34;org.springframework.data.redis.serializer.StringRedisSerializer&#34; /&gt;  
    &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id=&#34;springRedisClientImpl&#34; class=&#34;com.yc.redis.spring.clients.SpringRedisClientImpl&#34;&gt;
    &lt;property name=&#34;redisTemplate&#34; ref=&#34;redisTemplate&#34; /&gt;
&lt;/bean&gt;

</beans>

这样我们就可以来操作redis数据库了

再看看操作redis的帮助类,,它里面封装了我们一些基本的操作redis的方法

代码语言:javascript
复制
package com.yc.redis.spring.clients;

import java.util.Set;

public interface SpringRedisClient {
/**
* 存
* @param key
* @param value
/
public void setKey( String key, String value);
/
*
* 根据键取值
* @param key
* @return
/
public Object getKey( String key);
/
*
* 自增
* @param key
/
public void incr( String key);
/
*
* 在上一个元素的左边存
* @param key
* @param value
/
public void lPush( String key, String value);
/
*
* 查看是否有这个键
* @param key
* @return
/
public boolean checkKey( String key);
/
*
* 按键取
* @param key
* @return
/
public Object lIndex( String key);
/
*
* 求长度
* @param key
* @return
/
public Long lLength( String key);
/
*
* 从上一个元素的左边取值
* @param key
* @return
/
public String lPop( String key);
/
*
* 按正则表达式匹配的键取值
* @param pattern
* @return
*/
public Set<String> getKeys( String pattern);

}

看看它的实现,里面通过spring注入了一个RedisTemplate,这在spring的配置文件里面已经注册了,这样就可以访问redis数据库了

代码语言:javascript
复制
package com.yc.redis.spring.clients;

import java.io.Serializable;
import java.util.Set;

import org.springframework.data.redis.core.RedisTemplate;

public class SpringRedisClientImpl implements SpringRedisClient,Serializable {
/**
*
*/
private static final long serialVersionUID = -4213002642362857373L;
private RedisTemplate redisTemplate;

public void setRedisTemplate(RedisTemplate redisTemplate) {
    this.redisTemplate = redisTemplate;
}

@Override
public void setKey(String key, String value) {
    this.redisTemplate.opsForValue().set(key, value);
}

@Override
public Object getKey(String key) {
    return this.redisTemplate.opsForValue().get(key);
}

@Override
public void incr(String key) {
    this.redisTemplate.opsForValue().increment(key, 1);
}

@Override
public void lPush(String key, String value) {
    this.redisTemplate.opsForList().leftPush(key, value);
}

@Override
public boolean checkKey(String key) {
    return this.redisTemplate.hasKey(key);
}

@Override
public Object lIndex(String key) {
    return this.redisTemplate.opsForList().index(key, 0);
}

@Override
public Long lLength(String key) {
    return this.redisTemplate.opsForList().size(key);
}

@Override
public String lPop(String key) {
    return (String) this.redisTemplate.opsForList().leftPop(key);
}

@Override
public Set&lt;String&gt; getKeys(String pattern) {
    return this.redisTemplate.keys(pattern);
}

}

首先看看业务层,定义了三个接口方法,分别是顶,踩和刷新时查找顶和踩的数量

代码语言:javascript
复制
package com.yc.service;
public interface UserService {
public String Ding();
public String Cai() ;
public String[] Find() ;
}

下面看它的实现类

代码语言:javascript
复制
package com.yc.service.impl;

import java.io.Serializable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.yc.redis.spring.clients.SpringRedisClientImpl;
import com.yc.service.UserService;

import redis.clients.jedis.Jedis;
@Service("userServiceImpl")
public class UserServiceImpl implements UserService ,Serializable {
/**
*
*/
private static final long serialVersionUID = 1304876423677235894L;
@Autowired
private SpringRedisClientImpl springRedisClientImpl;//通过spring注入

@Override
public String Ding() {
    springRedisClientImpl.incr(&#34;User:ding&#34;);
    String num=(String) springRedisClientImpl.getKey(&#34;User:ding&#34;);
    return num;
}


public SpringRedisClientImpl getSpringRedisClientImpl() {
    return springRedisClientImpl;
}


public void setSpringRedisClientImpl(SpringRedisClientImpl springRedisClientImpl) {
    this.springRedisClientImpl = springRedisClientImpl;
}

@Override
public String Cai() {
    springRedisClientImpl.incr(&#34;User:cai&#34;);
    String num=(String) springRedisClientImpl.getKey(&#34;User:cai&#34;);
    return num;
}

@Override
public String[] Find() {
    String s[]=new String[2];
    s[0]= (String) springRedisClientImpl.getKey(&#34;User:ding&#34;);
    s[1]= (String) springRedisClientImpl.getKey(&#34;User:cai&#34;);
    return s;
}

}

最后大家可以看UserAction类了

代码语言:javascript
复制
package com.yc.web.actions;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

import com.opensymphony.xwork2.ActionSupport;
import com.yc.beans.User;
import com.yc.service.UserService;
import com.yc.service.impl.UserServiceImpl;
import com.yc.utils.JsonModel;
import com.yc.utils.JsonModel;

import redis.clients.jedis.Jedis;
@Controller("userAction")
public class UserAction extends ActionSupport {

/**
 * 
 */
private static final long serialVersionUID = 1825223373127715747L;
private JsonModel jsonModel = new JsonModel();
@Autowired
private UserServiceImpl userServiceImpl;


public JsonModel getJsonModel() {
    return jsonModel;
}

public void setJsonModel(JsonModel jsonModel) {
    this.jsonModel = jsonModel;
}

public String Ding() {
    User user = new User();
    String num = userServiceImpl.Ding();
    if (num != null &amp;&amp; !&#34;&#34;.equals(num)) {
        user.setDing(Integer.parseInt(num));
        jsonModel.setCode(1);
        jsonModel.setObj(user);
    }
    return SUCCESS;
}

public String Cai() {
    User user = new User();
    String num = userServiceImpl.Cai();
    if (num != null &amp;&amp; !&#34;&#34;.equals(num)) {
        user.setCai(Integer.parseInt(num));
        jsonModel.setCode(1);
        jsonModel.setObj(user);
    }
    return SUCCESS;
}

public String Find() {
    User user = new User();
    System.out.println(userServiceImpl);
    String num[] = userServiceImpl.Find();
    user.setDing(Integer.parseInt(num[0]));
    user.setCai(Integer.parseInt(num[1]));
    jsonModel.setCode(1);
    jsonModel.setObj(user);
    return SUCCESS;

}

}

这样所有的代码就都已经分析完了,搭建好redis服务后,就可以跑了,
整个项目的代码有需要的朋友可以下载
http://download.csdn.net/detail/tanggao1314/9487851