一段时间没有写过SSM的项目了,最近重新整合框架做了一个小Demo

学Java的萌新可以看一看;大佬呢,欢迎指出不足!

我一直钟爱挂机类游戏,同时也喜欢修仙和武侠小说,于是突发奇想,自己搞一个小游戏?

境界方面,我借鉴小说《武极天下》的境界划分

Github完整项目地址:https://github.com/EmYiQing/XiuXian

大家可以在我的Demo基础上增加其他功能,比如功法,门派,排行榜,甚至氪金系统,嘿嘿嘿

咳咳,回到正题:首先看一下最后的效果

前端用的阿里的SUI Mobile框架

登陆页面,Kaptcha实现验证码:

登陆成功后到达主页:

当经验值满了之后,就可以突破了,每个境界突破成功率不同:

前端代码(包括JS):

login.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>修仙游戏登录</title>
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<link rel="stylesheet"
    href="//g.alicdn.com/msui/sm/0.6.2/css/sm.min.css">
<link rel="stylesheet"
    href="//g.alicdn.com/msui/sm/0.6.2/css/sm-extend.min.css">
</head>
<body>
    <header class="bar bar-nav">
        <h1 class="title">修仙游戏登录</h1>
    </header>
    <div class="content">
        <div class="list-block">
            <ul>
                <li>
                    <div class="item-content">
                        <div class="item-media">
                            <i class="icon icon-form-name"></i>
                        </div>
                        <div class="item-inner">
                            <div class="item-input">
                                <input type="text" id="username" placeholder="用户名">
                            </div>
                        </div>
                    </div>
                </li>
                <li>
                    <div class="item-content">
                        <div class="item-media">
                            <i class="icon icon-form-email"></i>
                        </div>
                        <div class="item-inner">
                            <div class="item-input">
                                <input type="password" id="psw" placeholder="密码">
                            </div>
                        </div>
                    </div>
                </li>
                <li id="verifyPart">
                    <div class="item-content">
                        <div class="item-media">
                            <i class="icon icon-form-email"></i>
                        </div>
                        <div class="item-inner">
                            <label for="j_captcha" class="item-title label">验证码</label> <input
                                id="j_captcha" name="j_captcha" type="text"
                                class="form-control in" placeholder="验证码" />
                            <div class="item-input">
                                <img id="captcha_img" alt="点击更换" title="点击更换"
                                    onclick="changeVerifyCode(this)" src="/xiuxian/Kaptcha" />
                            </div>
                        </div>
                    </div>
                </li>
            </ul>
        </div>
        <div class="content-block">
            <div class="row">
                <div class="col-100">
                    <a href="#" class="button button-big button-fill" id="submit">登录</a>
                </div>
            </div>
        </div>
    </div>
    <script type='text/javascript'
        src='//g.alicdn.com/sj/lib/zepto/zepto.min.js' charset='utf-8'></script>
    <script type='text/javascript'
        src='//g.alicdn.com/msui/sm/0.6.2/js/sm.min.js' charset='utf-8'></script>
    <script type='text/javascript'
        src='//g.alicdn.com/msui/sm/0.6.2/js/sm-extend.min.js' charset='utf-8'></script>
    <script type="text/javascript">
        $(function() {
            var loginUrl = '/xiuxian/logincheck';
            $('#submit').click(function() {
                var userName = $('#username').val();
                var password = $('#psw').val();
                var verifyCodeActual = $('#j_captcha').val();
                $.ajax({
                    url : loginUrl,
                    async : false,
                    cache : false,
                    type : "post",
                    dataType : 'json',
                    data : {
                        userName : userName,
                        password : password,
                        verifyCodeActual : verifyCodeActual,
                    },
                    success : function(data) {
                        if (data.success) {
                            window.location.href = '/xiuxian/home';
                        } else {
                            $.toast('登录失败!' + data.errMsg);
                        }
                    }
                });
            });
        });
        function changeVerifyCode(img) {
            img.src = "/xiuxian/Kaptcha?" + Math.floor(Math.random() * 100);
        }
    </script>
</body>
</html>

home.html:

<html>
<head>
<link rel="stylesheet"
    href="//g.alicdn.com/msui/sm/0.6.2/css/sm.min.css">
<link rel="stylesheet"
    href="//g.alicdn.com/msui/sm/0.6.2/css/sm-extend.min.css">
<title>修仙世界</title>
</head>
<body>
    <header class="bar bar-nav">
        <h1 class="title">修仙世界</h1>
    </header>
    <div class="content">
        <div class="content-block">
            <div id="user"></div>
            <div id="the_state"></div>
            <div id="the_desc"></div>
        </div>
        <div class="content-padded grid-demo">
            <div style="text-align: center" id="exp"></div>
            <div style="text-align: center">
                <progress max="100" value="0" id="pg"></progress>
            </div>
            <p>
                <a class="button button-danger" onclick="breakState();">突破当前境界</a>
            </p>
        </div>
    </div>
    <script type='text/javascript'
        src='//g.alicdn.com/sj/lib/zepto/zepto.min.js' charset='utf-8'></script>
    <script type='text/javascript'
        src='//g.alicdn.com/msui/sm/0.6.2/js/sm.min.js' charset='utf-8'></script>
    <script type='text/javascript'
        src='//g.alicdn.com/msui/sm/0.6.2/js/sm-extend.min.js' charset='utf-8'></script>
    <script>
        //初始化数据URL
        var url = '/xiuxian/getinitinfo';
        //境界显示
        var state = document.getElementById('the_state');
        //境界描述显示
        var desc = document.getElementById('the_desc');
        //个人经验显示
        var exp = document.getElementById('exp');
        //个人姓名显示
        var user = document.getElementById('user');
        //个人经验数值
        var tempExp = 0;
        //当前境界总经验数值
        var tempTopExp = 0;
        //进度条
        var pg = document.getElementById('pg');
        //经验值不足时候无法突破
        var canBreak = false;
        //整数成功率
        var successRate = 0;

        //突破按钮点击处理
        function breakState() {
            if (canBreak == false) {
                $.toast("修为不足无法突破");
            } else {
                $.confirm("你当前突破的成功率是" + successRate + "%,确定尝试吗?", function() {
                    tryBreak();
                });
            }
        };

        //突破成功率处理
        var getRandom = function(probability) {
            var probability = probability * 100 || 1;
            var odds = Math.floor(Math.random() * 100);
            if (probability === 1) {
                return 1;
            }
            if (odds < probability) {
                return 1;
            } else {
                return 0;
            }
        };

        //尝试突破
        function tryBreak() {
            var rate = successRate / 100;
            var success = getRandom(rate);
            if (success) {
                submitBreak();
            } else {
                $.toast("道友,你突破失败了,损失经验" + tempTopExp);
                tempExp -= tempTopExp;
            }
        };

        //提交突破请求
        function submitBreak() {
            $.ajax({
                url : "/xiuxian/submitbreak",
                async : false,
                cache : false,
                type : "get",
                dataType : 'json',
                success : function(data) {
                    if (data.success) {
                        $.toast("恭喜,突破成功!");
                        window.location.reload();
                    } else {
                        $.toast('失败:' + data.errMsg);
                    }
                }
            });
        }

        //获取初始化信息
        $(function() {
            $.ajax({
                url : url,
                async : false,
                cache : false,
                type : "get",
                dataType : 'json',
                success : function(data) {
                    if (data.success) {
                        exp.innerText = "进度:" + data.user.exp + "/"
                                + data.state.stateExp;
                        tempExp = data.user.exp;
                        tempTopExp = data.state.stateExp;
                        if (tempExp >= tempTopExp) {
                            canBreak = true;
                        }
                        state.innerText = "当前境界:" + data.state.stateName;
                        desc.innerText = data.state.stateDesc;
                        user.innerText = data.user.username;
                        successRate = data.state.successRate;
                    } else {
                        $.toast('失败!' + data.errMsg);
                    }
                }
            });
        });
        //JS后台执行
        var tempTimer;
        document.addEventListener('visibilitychange', function() {
            var isHidden = document.hidden;
            if (isHidden) {
                tempTimer = setInterval(function(e) {
                    tempExp += 1;
                }, 1000);
            } else {
                clearInterval(tempTimer);
            }
        });
        //进度条设置
        setInterval(function(e) {
            if (pg.value != 100) {
                pg.value++;
            } else {
                tempExp += 1;
                exp.innerText = "进度:" + tempExp + "/" + tempTopExp;
                if (tempExp == tempTopExp) {
                    canBreak = true;
                }
                pg.value = 0;
            }
        }, 10);
        //每3秒进行一次数据同步
        setInterval(function(e) {
            submitExpChange();
        }, 3000);

        //提交数据
        function submitExpChange() {
            $.ajax({
                url : "/xiuxian/submitexpchange",
                async : false,
                cache : false,
                type : "get",
                dataType : 'json',
                data : {
                    exp : tempExp
                },
                success : function(data) {
                    if (data.success) {
                    }
                }
            });
        };
    </script>
</body>
</html>

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1" metadata-complete="true">
    <display-name>XiuXian</display-name>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    <!-- 乱码处理 -->
    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <!-- 验证码 -->
    <servlet>
        <servlet-name>Kaptcha</servlet-name>
        <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>
        <init-param>
            <param-name>kaptcha.border</param-name>
            <param-value>no</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.font.color</param-name>
            <param-value>red</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.char.string</param-name>
            <param-value>ACDEFGHJKMNPRSTUVWX23456789</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.char.length</param-name>
            <param-value>4</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.font.names</param-name>
            <param-value>Arial</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.image.width</param-name>
            <param-value>135</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.image.height</param-name>
            <param-value>50</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.font.color</param-name>
            <param-value>red</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.textproducer.font.size</param-name>
            <param-value>43</param-value>
        </init-param>
        <init-param>
            <param-name>kaptcha.noise.color</param-name>
            <param-value>black</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>Kaptcha</servlet-name>
        <url-pattern>/Kaptcha</url-pattern>
    </servlet-mapping>
    <!-- 配置Spring -->
    <servlet>
        <servlet-name>DispatcherServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring/spring-*.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>DispatcherServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

Spring配置文件:

spring-dao.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    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">
    <context:property-placeholder
        location="classpath:jdbc.properties" />
    <!-- 数据库连接池 -->
    <bean id="dataSource"
        class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <!-- 读取 -->
        <property name="driverClass" value="${jdbc.driver}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <property name="user" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <property name="maxPoolSize" value="30" />
        <property name="minPoolSize" value="10" />
        <property name="autoCommitOnClose" value="false" />
        <property name="checkoutTimeout" value="10000" />
        <property name="acquireRetryAttempts" value="2" />
    </bean>
    <!-- 配置SqlSessionFactory对象 -->
    <bean id="sqlSessionFactory"
        class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
        <!-- 配置MyBaties全局配置文件:mybatis-config.xml -->
        <property name="configLocation"
            value="classpath:mybatis-config.xml" />
        <!-- 使用别名 -->
        <property name="typeAliasesPackage"
            value="org.dreamtech.xiuxian.entity" />
        <!-- 扫描mapper文件 -->
        <property name="mapperLocations"
            value="classpath:mapper/*.xml" />
    </bean>

    <!-- 配置扫描dao接口包 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName"
            value="sqlSessionFactory" />
        <!-- 扫描 -->
        <property name="basePackage"
            value="org.dreamtech.xiuxian.dao" />
    </bean>
</beans>

spring-service.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    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/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!-- 扫描 -->
    <context:component-scan base-package="org.dreamtech.xiuxian.service" />
    <!-- 配置事务管理器 -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <!-- 注入数据库连接池 -->
        <property name="dataSource" ref="dataSource" />
    </bean>
    <!-- 配置基于注解的声明式事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" />
</beans>

spring-web.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    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/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
    <!-- 开启SpringMVC注解模式 -->
    <mvc:annotation-driven />
    <!-- 放行静态资源 -->
    <mvc:resources mapping="/resources/**"
        location="/resources/" />
    <mvc:default-servlet-handler />
    <!-- 定义视图解析器 -->
    <bean id="viewResolver"
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/html/" />
        <property name="suffix" value=".html" />
    </bean>
    <!-- 扫描 -->
    <context:component-scan
        base-package="org.dreamtech.xiuxian.web" />
    <!-- 过滤器 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/home" />
            <bean id="ShopInterceptor"
                class="org.dreamtech.xiuxian.interceptor.LoginInterceptor" />
        </mvc:interceptor>
    </mvc:interceptors>
</beans>

MyBatis配置文件:

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 配置全局属性 -->
    <settings>
        <!-- 使用JDBC的getGeneratedKeys获取数据库自增主键值 -->
        <setting name="useGeneratedKeys" value="true" />
        <!-- 使用列标签替换列别名 -->
        <setting name="useColumnLabel" value="true" />
        <!-- 开启驼峰命名转换 -->
        <setting name="mapUnderscoreToCamelCase" value="true" />
    </settings>
</configuration>

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>org.dreamtech</groupId>
    <artifactId>xiuxian</artifactId>
    <packaging>war</packaging>
    <version>0.0.1-SNAPSHOT</version>
    <name>xiuxian Maven Webapp</name>
    <url>http://maven.apache.org</url>

    <properties>
        <spring.version>4.3.7.RELEASE</spring.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!-- 日志 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.1</version>
        </dependency>
        <!-- 数据库 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.37</version>
        </dependency>
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.2</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.1</version>
        </dependency>
        <!-- 其他包 -->
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.8.7</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</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-web</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>commons-collections</groupId>
            <artifactId>commons-collections</artifactId>
            <version>3.2</version>
        </dependency>
        <!-- 验证码 -->
        <dependency>
            <groupId>com.github.penggle</groupId>
            <artifactId>kaptcha</artifactId>
            <version>2.3.2</version>
        </dependency>
    </dependencies>

    <build>
        <finalName>xiuxian</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

数据库配置文件:

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/xiuxian?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=xuyiqing

表的结构和数据:

-- ----------------------------
-- Table structure for tb_person
-- ----------------------------
DROP TABLE IF EXISTS `tb_person`;
CREATE TABLE `tb_person` (
  `) NOT NULL AUTO_INCREMENT,
  `) ',
  `state_id` ) ',
  `username` ) NOT NULL,
  `password` ) NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_person
-- ----------------------------
', '许无情', 'xuyiqing');

-- ----------------------------
-- Table structure for tb_state
-- ----------------------------
DROP TABLE IF EXISTS `tb_state`;
CREATE TABLE `tb_state` (
  `state_id` ) NOT NULL AUTO_INCREMENT,
  `state_name` ) NOT NULL,
  `state_exp` ) NOT NULL,
  `success_rate` ) NOT NULL,
  `state_desc` ) DEFAULT NULL,
  PRIMARY KEY (`state_id`)
) ENGINE DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tb_state
-- ----------------------------
', '初入修武一途');
', '肉体是修炼的根本');
', '修炼五脏六腑');
', '修炼经脉');
', '修炼骨骼');
', '世俗界的强者');

Java代码:

实体类只有两个,个人信息和境界信息,以后可以完善其他的功能

package org.dreamtech.xiuxian.entity;

/**
 * 个人信息
 *
 * @author Xu Yiqing
 *
 */
public class Person {

    private String userId;
    private Integer exp;
    private String stateId;
    private String username;
    private String password;

    public String getUserId() {
        return userId;
    }

    public void setUserId(String userId) {
        this.userId = userId;
    }

    public Integer getExp() {
        return exp;
    }

    public void setExp(Integer exp) {
        this.exp = exp;
    }

    public String getStateId() {
        return stateId;
    }

    public void setStateId(String stateId) {
        this.stateId = stateId;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

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

    @Override
    public String toString() {
        return "Person [userId=" + userId + ", exp=" + exp + ", stateId=" + stateId + ", username=" + username
                + ", password=" + password + "]";
    }

}
package org.dreamtech.xiuxian.entity;

/**
 * 境界信息
 *
 * @author Xu Yiqing
 *
 */
public class State {

    private String stateId;
    private String stateName;
    private Integer stateExp;
    private Integer successRate;
    private String stateDesc;

    public String getStateId() {
        return stateId;
    }

    public void setStateId(String stateId) {
        this.stateId = stateId;
    }

    public String getStateName() {
        return stateName;
    }

    public void setStateName(String stateName) {
        this.stateName = stateName;
    }

    public Integer getStateExp() {
        return stateExp;
    }

    public void setStateExp(Integer stateExp) {
        this.stateExp = stateExp;
    }

    public Integer getSuccessRate() {
        return successRate;
    }

    public void setSuccessRate(Integer successRate) {
        this.successRate = successRate;
    }

    public String getStateDesc() {
        return stateDesc;
    }

    public void setStateDesc(String stateDesc) {
        this.stateDesc = stateDesc;
    }

    @Override
    public String toString() {
        return "State [stateId=" + stateId + ", stateName=" + stateName + ", stateExp=" + stateExp + ", successRate="
                + successRate + ", stateDesc=" + stateDesc + "]";
    }

}

Dao层:

package org.dreamtech.xiuxian.dao;

import java.util.List;

import org.apache.ibatis.annotations.Param;
import org.dreamtech.xiuxian.entity.Person;
import org.dreamtech.xiuxian.entity.State;

/**
 * 主页Dao层
 *
 * @author Xu Yiqing
 *
 */
public interface HomeDao {
    /**
     * 根据用户的stateID查询对应境界信息
     *
     * @param stateId 用户的stateID
     * @return 境界信息
     */
    State getInitInfoByStateId(String stateId);

    /**
     * 获取所有境界信息
     *
     * @return 境界信息列表
     */
    List<State> getStateList();

    /**
     * 自动存储经验值
     *
     * @param userId 用户ID
     * @param exp    存储的经验值
     * @return 影响的行数
     */
    int saveExpChange(@Param("userId") String userId, @Param("exp") String exp);

    /**
     * 突破当前境界
     *
     * @param userId     用户ID
     * @param newStateId 突破后的境界ID
     * @return 影响的行数
     */
    int breakState(@Param("userId") String userId, @Param("stateId") String stateId);

    /**
     * 根据用户ID获得用户信息
     *
     * @param userId 用户ID
     * @return 用户对象
     */
    Person getUserById(String userId);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dreamtech.xiuxian.dao.HomeDao">
    <select id="getInitInfoByStateId" resultType="State">
        SELECT
        state_id,state_name,state_exp,success_rate,state_desc
        FROM
        tb_state
        WHERE
        state_id=#{stateId}
    </select>
    <select id="getStateList" resultType="State">
        SELECT
        state_id,state_name,state_exp,success_rate,state_desc
        FROM
        tb_state
        ORDER BY
        state_id
    </select>
    <update id="saveExpChange">
        UPDATE
        tb_person
        SET
        exp=#{exp}
        WHERE
        user_id=#{userId}
    </update>
    <update id="breakState">
        UPDATE
        tb_person
        SET
        state_id=#{stateId}
        WHERE
        user_id=#{userId}
    </update>
    <select id="getUserById" resultType="Person">
        SELECT
        user_id,exp,state_id,username
        FROM
        tb_person
        WHERE
        user_id=#{userId}
    </select>
</mapper>
    
package org.dreamtech.xiuxian.dao;

import org.apache.ibatis.annotations.Param;
import org.dreamtech.xiuxian.entity.Person;

public interface PersonDao {
    /**
     * 根据用户名和密码得到用户信息
     *
     * @return 用户
     */
    Person getPersonByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.dreamtech.xiuxian.dao.PersonDao">
    <select id="getPersonByUsernameAndPassword" resultType="Person">
        SELECT
        user_id,exp,state_id,username,password
        FROM
        tb_person
        WHERE
        username=#{username}
        AND
        password=#{password}
    </select>
</mapper>
    

Service层:

package org.dreamtech.xiuxian.service;

import org.dreamtech.xiuxian.entity.Person;
import org.dreamtech.xiuxian.entity.State;

/**
 * 首页服务层
 *
 * @author Xu Yiqing
 *
 */
public interface HomeService {
    /**
     * 根据境界ID获得初始化信息
     *
     * @param stateId 境界ID
     * @return 境界信息
     */
    State getInitInfoByStateId(String stateId);

    /**
     * 每3秒进行一次经验保存
     *
     * @param userId
     * @param exp
     * @return
     */
    int saveExpChange(String userId, String exp);

    /**
     * 突破
     *
     * @param user 用户
     * @return 返回信息
     */
    int breakState(Person user);

    /**
     * 根据用户ID得到用户信息
     *
     * @param userId 用户ID
     * @return 用户信息
     */
    Person getUserById(String userId);
}
package org.dreamtech.xiuxian.service.impl;

import java.util.List;

import org.dreamtech.xiuxian.dao.HomeDao;
import org.dreamtech.xiuxian.entity.Person;
import org.dreamtech.xiuxian.entity.State;
import org.dreamtech.xiuxian.service.HomeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class HomeServiceImpl implements HomeService {
    // 满级
    public static final Integer MAX_STATE = -1;
    // 突破成功
    public static final Integer BREAK_SUCCESS = 1;
    // 内部错误
    public static final Integer INNER_ERROR = 0;
    @Autowired
    private HomeDao homeDao;

    @Override
    public State getInitInfoByStateId(String stateId) {
        return homeDao.getInitInfoByStateId(stateId);
    }

    @Override
    public int saveExpChange(String userId, String exp) {
        return homeDao.saveExpChange(userId, exp);
    }

    @Override
    @Transactional
    public int breakState(Person user) {
        List<State> stateList = homeDao.getStateList();
        State state = null;
        if (Integer.parseInt(user.getStateId()) <= Integer.parseInt(stateList.get(stateList.size() - 1).getStateId())) {
            for (State tempState : stateList) {
                if (tempState.getStateId().equals(user.getStateId())) {
                    state = tempState;
                }
            }
            String newStateId = (Integer.parseInt(user.getStateId()) + 1) + "";
            int effectedNum = homeDao.breakState(user.getUserId(), newStateId);
            if (effectedNum > 0) {
                Person newUser = homeDao.getUserById(user.getUserId());
                homeDao.saveExpChange(newUser.getUserId(), (newUser.getExp() - state.getStateExp()) + "");
            } else {
                return INNER_ERROR;
            }
        } else {
            return MAX_STATE;
        }
        return BREAK_SUCCESS;
    }

    @Override
    public Person getUserById(String userId) {
        return homeDao.getUserById(userId);
    }

}
package org.dreamtech.xiuxian.service;

import org.dreamtech.xiuxian.entity.Person;

public interface PersonService {
    /**
     * 根据用户名和密码得到用户信息
     *
     * @return 用户
     */
    Person getPersonByUsernameAndPassword(String username, String password);
}
package org.dreamtech.xiuxian.service.impl;

import org.dreamtech.xiuxian.dao.PersonDao;
import org.dreamtech.xiuxian.entity.Person;
import org.dreamtech.xiuxian.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class PersonServiceImpl implements PersonService {
    @Autowired
    private PersonDao personDao;

    @Override
    public Person getPersonByUsernameAndPassword(String username, String password) {
        if (username != null && !username.equals("")) {
            username = username.replace(" ", "");
        } else {
            throw new RuntimeException("username is null");
        }
        if (password != null && !password.equals("")) {
            password = password.replace(" ", "");
        } else {
            throw new RuntimeException("password is null");
        }
        Person person = null;
        try {
            person = personDao.getPersonByUsernameAndPassword(username, password);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("error:PersonDao.getPersonByUsernameAndPassword");
        }
        return person;
    }

}

Web层:

package org.dreamtech.xiuxian.web;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dreamtech.xiuxian.entity.Person;
import org.dreamtech.xiuxian.entity.State;
import org.dreamtech.xiuxian.service.HomeService;
import org.dreamtech.xiuxian.service.impl.HomeServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/**
 * 主页控制器
 *
 * @author Xu Yiqing
 *
 */
@RestController
public class HomeController {
    @Autowired
    private HomeService homeService;

    /**
     * 获得初始化信息
     *
     * @param request 请求
     * @return
     */
    @RequestMapping(value = "getinitinfo", method = RequestMethod.GET)
    private Map<String, Object> getInitInfo(HttpServletRequest request) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        Person person = (Person) request.getSession().getAttribute("user");
        if (person != null) {
            if (person.getUsername() != null) {
                modelMap.put("user", person);
            }
            if (person.getStateId() != null) {
                State state = homeService.getInitInfoByStateId(person.getStateId());
                if (state != null && state.getStateId() != null) {
                    modelMap.put("success", true);
                    modelMap.put("state", state);
                } else {
                    modelMap.put("success", false);
                    modelMap.put("errMsg", "未知错误");
                }
            }
        } else {
            modelMap.put("success", false);
            modelMap.put("errMsg", "非法操作");
        }
        return modelMap;
    }

    /**
     * 每3秒进行一次经验保存
     *
     * @param request 请求
     * @return
     */
    @RequestMapping(value = "submitexpchange", method = RequestMethod.GET)
    private Map<String, Object> sumbitExp(HttpServletRequest request) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        Person user = (Person) request.getSession().getAttribute("user");
        String userId = user.getUserId();
        String exp = request.getParameter("exp");
        try {
            int effectedNum = homeService.saveExpChange(userId, exp);
            if (effectedNum < 1) {
                modelMap.put("success", false);
                modelMap.put("errMsg", "非法操作");
            } else {
                modelMap.put("success", true);
            }
        } catch (Exception e) {
            modelMap.put("success", false);
            modelMap.put("errMsg", e.toString());
        }
        return modelMap;
    }

    /**
     * 突破
     *
     * @param request 请求
     * @return
     */
    @RequestMapping(value = "submitbreak", method = RequestMethod.GET)
    private Map<String, Object> sumbitBreak(HttpServletRequest request) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        Person user = (Person) request.getSession().getAttribute("user");
        try {
            int result = homeService.breakState(user);
            if (result == HomeServiceImpl.BREAK_SUCCESS) {
                modelMap.put("success", true);
                Person newUser = homeService.getUserById(user.getUserId());
                request.getSession().setAttribute("user", newUser);
            } else if (result == HomeServiceImpl.MAX_STATE) {
                modelMap.put("success", false);
                modelMap.put("errMsg", "道友的境界已经达到了巅峰");
            } else if (result == HomeServiceImpl.INNER_ERROR) {
                modelMap.put("success", false);
                modelMap.put("errMsg", "未知错误");
            }
        } catch (Exception e) {
            modelMap.put("success", false);
            modelMap.put("errMsg", e.toString());
        }
        return modelMap;
    }
}
package org.dreamtech.xiuxian.web;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * 页面控制器
 *
 * @author Xu Yiqing
 *
 */
@Controller
public class PageController {
    /**
     * 登陆页面
     *
     * @return 登录页
     */
    @RequestMapping("login")
    private String login() {
        return "login";
    }

    /**
     * 首页
     *
     * @return 首页
     */
    @RequestMapping("home")
    private String test() {
        return "home";
    }
}
package org.dreamtech.xiuxian.web;

import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.dreamtech.xiuxian.entity.Person;
import org.dreamtech.xiuxian.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.google.code.kaptcha.Constants;

/**
 * 登录页控制器
 *
 * @author Xu Yiqing
 *
 */
@RestController
public class PersonController {
    @Autowired
    private PersonService personService;

    /**
     * 登陆
     *
     * @param request 请求
     * @return
     */
    @RequestMapping(value = "logincheck", method = RequestMethod.POST)
    private Map<String, Object> login(HttpServletRequest request) {
        Map<String, Object> modelMap = new HashMap<String, Object>();
        String username = request.getParameter("userName");
        String password = request.getParameter("password");
        String verifyCodeActual = request.getParameter("verifyCodeActual");
        String verifyCodeExpected = (String) request.getSession().getAttribute(Constants.KAPTCHA_SESSION_KEY);
        if (verifyCodeActual == null || !verifyCodeActual.equals(verifyCodeExpected)) {
            modelMap.put("errMsg", "验证码错误");
            modelMap.put("success", false);
        }
        try {
            Person person = personService.getPersonByUsernameAndPassword(username, password);
            System.out.println("[-*-User: " + person.getUsername() + " login-*-]");
            request.getSession().setAttribute("user", person);
            if (person != null && person.getUserId() != null) {
                modelMap.put("success", true);
            } else {
                modelMap.put("success", false);
                modelMap.put("errMsg", "用户名或密码错误");
            }
        } catch (Exception e) {
            modelMap.put("success", false);
            modelMap.put("errMsg", "用户名或密码错误");
        }
        return modelMap;
    }
}

拦截器:

package org.dreamtech.xiuxian.interceptor;

import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dreamtech.xiuxian.entity.Person;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * 登录验证拦截器
 *
 * @author Xu Yiqing
 *
 */
public class LoginInterceptor extends HandlerInterceptorAdapter {

    /**
     * 事先拦截
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {

        Object userObj = request.getSession().getAttribute("user");
        if (userObj != null) {
            Person user = (Person) userObj;
            if (user != null && user.getUserId() != null) {
                return true;
            }
        }
        PrintWriter out = response.getWriter();
        out.println("<html>");
        out.println("<script>");
        out.println("window.location.href='/xiuxian/login'");
        out.println("</script>");
        out.println("</html>");
        return false;
    }
}

SSM+Maven+MySQL实现简易的挂机修仙页游的更多相关文章

  1. SSM maven框架下载简易版

    1.前台一个a标签,写个地址就行了 例如 <a href="${pageContext.request.contextPath}/fileDownLoad">前去下载& ...

  2. 从零开始搭建框架SSM+Redis+Mysql(二)之MAVEN项目搭建

    从零开始搭建框架SSM+Redis+Mysql(二)之MAVEN项目搭建 废话不说,直接撸步骤!!! 1.创建主项目:ncc-parent 选择maven创建项目,注意在创建项目中,packing选择 ...

  3. 从零开始搭建框架SSM+Redis+Mysql(一)之摘要

    从零开始搭建框架SSM+Redis+Mysql(一)之摘要 本文章为本人实际的操作后的回忆笔记,如果有步骤错漏,希望来信307793969@qq.com或者评论指出. 本文章只体现过程,仅体现操作流程 ...

  4. ssm maven spring AOP读写分离

    ssm maven spring AOP读写分离 总体流程 配置最开始写在pom.xml文件,解析到数据库配置文件,再解析到spring配置文件. 自定义注解DataSource:通过这个注解并且在s ...

  5. bootstrap+Ajax+SSM(maven搭建)实现增删改查

    https://www.jianshu.com/p/d76316b48e3e 源码: https://github.com/Ching-Lee/crud 功能点: 分页 数据校验 ajax Rest风 ...

  6. ssm+maven+pageHelper搭建maven项目实现快速分页

    ssm+maven+pageHelper搭建maven项目实现快速分页 PageHelper分页使用: 插件的环境引入: 1.pom文件中引入分页插件的资源位置: <dependency> ...

  7. SSM+Maven+IDEA增删改查

    开发工具 IntelliJ IDEA Apache-tomcat-9.0 JDK 1.8 MySQL 8.0.11 Maven 3.5.4 IDEA+Maven搭建项目骨架 1. 新建Maven项目: ...

  8. Spring学习总结(五)——Spring整合MyBatis(Maven+MySQL)二

    接着上一篇博客<Spring整合MyBatis(Maven+MySQL)一>继续. Spring的开放性和扩张性在J2EE应用领域得到了充分的证明,与其他优秀框架无缝的集成是Spring最 ...

  9. Hibernate+maven+mysql

    最近在研究hibernate,想建立一个简单的Hibernate+maven+mysql工程,网上找了一大堆的示例,要么看不懂结构,要么就是缺少必要文件.总之都没有成功,结果无意在一个外文网上找了一个 ...

随机推荐

  1. LVM基本应用,扩展及缩减实现!

    LVM概述 [百度百科] LVM是逻辑盘卷管理(LogicalVolumeManager)的简称,它是Linux环境下对磁盘分区进行管理的一种机制,LVM是建立在硬盘和 分区之上的一个逻辑层,来提高磁 ...

  2. 用shell处理以下内容 1、按单词出现频率降序排序! 2、按字母出现频率降序排序! the squid project provides a number of resources toassist users design,implement and support squid installations. Please browsethe documentation and support

    此题目有多种解法,sed.awk.tr等等,都可以解决此题,命令运用灵活多变. 编写shell脚本no_20.sh 解法1: #!/bin/bash ###-------------CopyRight ...

  3. 如何提高缓存命中率(Redis)

    缓存命中率的介绍 命中:可以直接通过缓存获取到需要的数据. 不命中:无法直接通过缓存获取到想要的数据,需要再次查询数据库或者执行其它的操作.原因可能是由于缓存中根本不存在,或者缓存已经过期. 通常来讲 ...

  4. PAT1090:Highest Price in Supply Chain

    1090. Highest Price in Supply Chain (25) 时间限制 200 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 C ...

  5. 二十、Hadoop学记笔记————Hive On Hbase

    Hive架构图: 一般用户接口采用命令行操作, hive与hbase整合之后架构图: 使用场景 场景一:通过insert语句,将文件或者table中的内容加入到hive中,由于hive和hbase已经 ...

  6. elasticsearch 的安装配置与spring boot的整合应用

    linux上的elasticsearch安装 一.下载elasticsearch 直接进入elasticsearch的官网,下载最新的安装包:https://www.elastic.co/downlo ...

  7. SVN更新失败,提示locked 怎么破

    有时在svn更新或提交代码时,会报错,让你cleanup  如果cleanup解决不了,就要删除被锁定的文件夹下的文件,然后就可以更新或提交了 怎么做呢? 1.首先在CMD中进入你工作目录被锁定的文件 ...

  8. 20个大大节省你时间的HTML5开发工具

    Rendera 如果你希望有个环境可以测试.浏览和体验各种不同的 CSS/HTML 和 JavaScript 代码,Rendera 为你提供了实时的运行结果.类似 RunJS. Patternizer ...

  9. Android 进阶 教你打造 Android 中的 IOC 框架 【ViewInject】 (下)

    上一篇博客我们已经带大家简单的吹了一下IoC,实现了Activity中View的布局以及控件的注入,如果你不了解,请参考:Android 进阶 教你打造 Android 中的 IOC 框架 [View ...

  10. scala 访问阿里云oss

    我们的数据一天就一个T,数据量不断增大,集群磁盘有限,所以把冷数据放到了oss,偶尔会使用到冷数据,如果使用的时候还的从oss上拉数据这样很浪费时间后来想了个办法可以直接获取到oss上的数据.案例:o ...