转自:http://blog.csdn.net/zoutongyuan/article/details/41379851
一直想写这篇文章,前段时间 痴迷于JavaScript、NodeJs、AngularJs,做了大量的研究,对前后端交互有了更深层次的认识。
今天抽个时间写这篇文章,我有预感,这将是一篇很详细的文章,详细的配置,详细的注释,看起来应该很容易懂。
用最合适的技术去实现,并不断追求最佳实践。这就是架构之道。
希望这篇文章能给你们带来一些帮助,同时希望你们可以为这个项目贡献你的想法。
源码地址:
看我们的项目结构:
是一个典型的Maven 项目 :
src/main/java:存放java源文件
src/main/resources:存放程序资源、配置文件
src/test/java:存放测试代码文件
src/main/webapp:web根目录
pom.xml : maven项目配置文件,管理依赖,编译,打包
主要的后端架构:Spring + Spring MVC + Mybatis + Apache Shiro
前端界面主要使用MetroNic 模板,
先看我们搭建完成,跑起来的效果,这样你才有兴趣看下去:
你可以 在github 上 checkout quick4j项目 查看 ,并跟下面步骤 来搭建:
强烈建议你,checkout https://github.com/starzou/quick4j ,在本地跑起来,再试着自己搭建框架
1、首先创建 maven 项目 ,用 idea 、eclipse 或 mvn 命令行都行
2、配置 pom.xml ,添加框架依赖
3、配置web.xml
web.xml是一个项目的核心,看看它的一些配置:
配置 ContextLoaderListener 监听器
配置Spring字符编码过滤器
配置shiro 安全过滤器
配置Spring MVC 核心控制器 DispatcherServlet
配置一些页面
spring 和 apache shiro 是由一个 ContextLoaderListener 监听器 加载的配置文件,并初始化
4、spring配置:
applicationContext.xml
application.properties
-
##JDBC Global Setting
-
jdbc.driver=com.mysql.jdbc.Driver
-
jdbc.url=jdbc:mysql://localhost:3306/quick4j?useUnicode=true&characterEncoding=utf-8
-
jdbc.username=root
-
jdbc.password=admin123
-
-
##DataSource Global Setting
-
-
#配置初始化大小、最小、最大
-
ds.initialSize=1
-
ds.minIdle=1
-
ds.maxActive=20
-
-
#配置获取连接等待超时的时间
-
ds.maxWait=60000
-
-
#配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
-
ds.timeBetweenEvictionRunsMillis=60000
-
-
#配置一个连接在池中最小生存的时间,单位是毫秒
-
ds.minEvictableIdleTimeMillis=300000
ehcache.xml
-
xml version="1.0" encoding="UTF-8"?>
-
<ehcache updateCheck="false" name="txswx-ehcache">
-
<diskStore path="java.io.tmpdir"/>
-
-
<defaultCache maxEntriesLocalHeap="10000" eternal="true" timeToIdleSeconds="300" timeToLiveSeconds="600"
-
overflowToDisk="true" maxEntriesLocalDisk="100000"/>
-
ehcache>
5、Apache Shiro 配置 : 要配置realms bean
-
xml version="1.0" encoding="UTF-8"?>
-
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:util="http://www.springframework.org/schema/util"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xsi:schemaLocation="
-
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
-
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
-
-
<description>apache shiro配置description>
-
-
<bean id="shiroFilter" class="org.apache.shiro.spring.web.ShiroFilterFactoryBean">
-
<property name="securityManager" ref="securityManager"/>
-
<property name="loginUrl" value="/rest/page/login"/>
-
<property name="successUrl" value="/rest/index"/>
-
<property name="unauthorizedUrl" value="/rest/page/401"/>
-
<property name="filterChainDefinitions">
-
<value>
-
-
/app/** = anon
-
/assets/** = anon
-
-
/rest/user/login = anon
-
-
/** = authc
-
value>
-
property>
-
bean>
-
-
-
<bean id="shiroEhcacheManager" class="org.apache.shiro.cache.ehcache.EhCacheManager">
-
<property name="cacheManagerConfigFile" value="classpath:ehcache-shiro.xml"/>
-
bean>
-
-
-
<bean id="sessionDAO" class="org.apache.shiro.session.mgt.eis.MemorySessionDAO"/>
-
-
-
<bean id="sessionManager" class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
-
<property name="sessionDAO" ref="sessionDAO"/>
-
bean>
-
-
-
<bean id="securityManager" class="org.apache.shiro.web.mgt.DefaultWebSecurityManager">
-
<property name="realms">
-
<list>
-
<ref bean="securityRealm"/>
-
list>
-
property>
-
-
-
-
bean>
-
-
-
<bean id="lifecycleBeanPostProcessor" class="org.apache.shiro.spring.LifecycleBeanPostProcessor"/>
-
-
beans>
ehcache-shiro.xml
-
<ehcache updateCheck="false" name="shiroCache">
-
-
<defaultCache
-
maxElementsInMemory="10000"
-
eternal="false"
-
timeToIdleSeconds="120"
-
timeToLiveSeconds="120"
-
overflowToDisk="false"
-
diskPersistent="false"
-
diskExpiryThreadIntervalSeconds="120"
-
/>
-
ehcache>
6、MyBatis 配置
-
xml version="1.0" encoding="UTF-8" ?>
-
-
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
-
"http://mybatis.org/dtd/mybatis-3-config.dtd">
-
<configuration>
-
<properties>
-
<property name="dialectClass" value="com.eliteams.quick4j.core.feature.orm.dialect.MySql5Dialect"/>
-
properties>
-
-
-
<settings>
-
-
-
<setting name="cacheEnabled" value="true"/>
-
-
-
<setting name="lazyLoadingEnabled" value="true"/>
-
-
-
<setting name="multipleResultSetsEnabled" value="true"/>
-
-
-
<setting name="useColumnLabel" value="true"/>
-
-
-
<setting name="useGeneratedKeys" value="false"/>
-
-
-
<setting name="autoMappingBehavior" value="PARTIAL"/>
-
-
-
-
-
-
-
-
-
<setting name="safeRowBoundsEnabled" value="false"/>
-
-
-
<setting name="mapUnderscoreToCamelCase" value="true"/>
-
-
-
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
-
-
-
<setting name="aggressiveLazyLoading" value="false"/>
-
-
settings>
-
-
<typeAliases>
-
<package name="com.eliteams.quick4j.web.model"/>
-
<package name="com.eliteams.quick4j.web.enums"/>
-
typeAliases>
-
-
<plugins>
-
<plugin interceptor="com.eliteams.quick4j.core.feature.orm.mybatis.PaginationResultSetHandlerInterceptor"/>
-
<plugin interceptor="com.eliteams.quick4j.core.feature.orm.mybatis.PaginationStatementHandlerInterceptor"/>
-
plugins>
-
-
configuration>
7、Spring MVC 配置
-
xml version="1.0" encoding="UTF-8"?>
-
<beans xmlns="http://www.springframework.org/schema/beans"
-
xmlns:aop="http://www.springframework.org/schema/aop"
-
xmlns:context="http://www.springframework.org/schema/context"
-
xmlns:mvc="http://www.springframework.org/schema/mvc"
-
xmlns:tx="http://www.springframework.org/schema/tx"
-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-
xmlns:p="http://www.springframework.org/schema/p"
-
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
-
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.xsd
-
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
-
-
-
<context:component-scan base-package="com.eliteams.quick4j.web.controller"/>
-
-
-
-
<mvc:annotation-driven validator="validator"/>
-
-
-
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean">
-
<property name="providerClass" value="org.hibernate.validator.HibernateValidator"/>
-
-
<property name="validationMessageSource" ref="messageSource"/>
-
bean>
-
-
-
<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
-
<property name="basenames">
-
<list>
-
-
<value>classpath:messagesvalue>
-
<value>classpath:org/hibernate/validator/ValidationMessagesvalue>
-
list>
-
property>
-
<property name="useCodeAsDefaultMessage" value="false"/>
-
<property name="defaultEncoding" value="UTF-8"/>
-
<property name="cacheSeconds" value="60"/>
-
bean>
-
-
<mvc:interceptors>
-
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor"/>
-
mvc:interceptors>
-
-
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.CookieLocaleResolver">
-
<property name="defaultLocale" value="zh_CN"/>
-
bean>
-
-
-
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
-
<property name="messageConverters">
-
<list>
-
<ref bean="mappingJacksonHttpMessageConverter"/>
-
list>
-
property>
-
bean>
-
<bean id="mappingJacksonHttpMessageConverter"
-
class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
-
<property name="supportedMediaTypes">
-
<list>
-
<value>text/plain;charset=UTF-8value>
-
<value>application/json;charset=UTF-8value>
-
list>
-
property>
-
bean>
-
-
-
-
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
-
p:prefix="/WEB-INF/views/" p:suffix=".jsp"/>
-
-
-
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
-
<property name="defaultEncoding" value="utf-8"/>
-
<property name="maxUploadSize" value="10485760000"/>
-
<property name="maxInMemorySize" value="40960"/>
-
bean>
-
-
-
<aop:config proxy-target-class="true">aop:config>
-
<bean class="org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor">
-
<property name="securityManager" ref="securityManager"/>
-
bean>
-
-
beans>
messages.properties : hibernate-validator 配置文件,国际化资源文件
-
#user
-
user.username.null=用户名不能为空
-
user.password.null=密码不能为空
log4j.properties :
-
# DEBUG,INFO,WARN,ERROR,FATAL
-
LOG_LEVEL=INFO
-
-
log4j.rootLogger=${LOG_LEVEL},CONSOLE,FILE
-
-
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
-
log4j.appender.CONSOLE.Encoding=utf-8
-
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
-
#log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{8}@(%F:%L):%m%n
-
log4j.appender.CONSOLE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss} %C{1}@(%F:%L):%m%n
-
-
log4j.appender.FILE=org.apache.log4j.DailyRollingFileAppender
-
log4j.appender.FILE.File=${catalina.base}/logs/quick4j.log
-
log4j.appender.FILE.Encoding=utf-8
-
log4j.appender.FILE.DatePattern='.'yyyy-MM-dd
-
log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
-
#log4j.appender.FILE.layout=org.apache.log4j.HTMLLayout
-
log4j.appender.FILE.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH\:mm\:ss} %C{8}@(%F\:%L)\:%m%n
quick4j.sql
-
/*
-
SQLyog 企业版 - MySQL GUI v8.14
-
MySQL - 5.5.27 : Database - quick4j
-
*********************************************************************
-
*/
-
-
-
/*!40101 SET NAMES utf8 */;
-
-
/*!40101 SET SQL_MODE=''*/;
-
-
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
-
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
-
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
-
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
-
CREATE DATABASE /*!32312 IF NOT EXISTS*/`quick4j` /*!40100 DEFAULT CHARACTER SET utf8 */;
-
-
USE `quick4j`;
-
-
/*Table structure for table `permission` */
-
-
DROP TABLE IF EXISTS `permission`;
-
-
CREATE TABLE `permission` (
-
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '权限id',
-
`permission_name` varchar(32) DEFAULT NULL COMMENT '权限名',
-
`permission_sign` varchar(128) DEFAULT NULL COMMENT '权限标识,程序中判断使用,如"user:create"',
-
`description` varchar(256) DEFAULT NULL COMMENT '权限描述,UI界面显示使用',
-
PRIMARY KEY (`id`)
-
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='权限表';
-
-
/*Data for the table `permission` */
-
-
insert into `permission`(`id`,`permission_name`,`permission_sign`,`description`) values (1,'用户新增','user:create',NULL);
-
-
/*Table structure for table `role` */
-
-
DROP TABLE IF EXISTS `role`;
-
-
CREATE TABLE `role` (
-
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '角色id',
-
`role_name` varchar(32) DEFAULT NULL COMMENT '角色名',
-
`role_sign` varchar(128) DEFAULT NULL COMMENT '角色标识,程序中判断使用,如"admin"',
-
`description` varchar(256) DEFAULT NULL COMMENT '角色描述,UI界面显示使用',
-
PRIMARY KEY (`id`)
-
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='角色表';
-
-
/*Data for the table `role` */
-
-
insert into `role`(`id`,`role_name`,`role_sign`,`description`) values (1,'admin','admin','管理员');
-
-
/*Table structure for table `role_permission` */
-
-
DROP TABLE IF EXISTS `role_permission`;
-
-
CREATE TABLE `role_permission` (
-
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表id',
-
`role_id` bigint(20) unsigned DEFAULT NULL COMMENT '角色id',
-
`permission_id` bigint(20) unsigned DEFAULT NULL COMMENT '权限id',
-
PRIMARY KEY (`id`)
-
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='角色与权限关联表';
-
-
/*Data for the table `role_permission` */
-
-
insert into `role_permission`(`id`,`role_id`,`permission_id`) values (1,2,1);
-
-
/*Table structure for table `user` */
-
-
DROP TABLE IF EXISTS `user`;
-
-
CREATE TABLE `user` (
-
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户id',
-
`username` varchar(50) DEFAULT NULL COMMENT '用户名',
-
`password` char(64) DEFAULT NULL COMMENT '密码',
-
`state` varchar(32) DEFAULT NULL COMMENT '状态',
-
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
-
PRIMARY KEY (`id`)
-
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='用户表';
-
-
/*Data for the table `user` */
-
-
insert into `user`(`id`,`username`,`password`,`state`,`create_time`) values (1,'starzou','8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92',NULL,'2014-07-17 12:59:08');
-
-
/*Table structure for table `user_role` */
-
-
DROP TABLE IF EXISTS `user_role`;
-
-
CREATE TABLE `user_role` (
-
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '表id',
-
`user_id` bigint(20) unsigned DEFAULT NULL COMMENT '用户id',
-
`role_id` bigint(20) unsigned DEFAULT NULL COMMENT '角色id',
-
PRIMARY KEY (`id`)
-
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='用户与角色关联表';
-
-
/*Data for the table `user_role` */
-
-
insert into `user_role`(`id`,`user_id`,`role_id`) values (1,1,1);
-
-
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
-
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
-
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
-
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;