发表于: 2016-06-23 14:49:02
2 1949
1、编写sql脚本:
create database xztest4;
use xztest4;
CREATE table profession
(
pid int auto_increment primary key comment '主键',
pname varchar(50) not null comment '职业名称',
create_at bigint comment '创建时间',
update_at bigint comment '修改时间',
qq_group varchar(20) comment '职业qq群',
companpy_number int comment '求职企业数量',
pro_threshold int comment '职业门槛',
difficulty int comment '难易程度',
introdution varchar(500) comment '职业简介',
duties varchar(2000) comment '工作内容',
skills varchar(2000) comment '所需技能',
prospect varchar(500) comment '职业前景',
acc_threshold varchar(500) comment '准入门槛',
candidate varchar(200) comment '谁更合适',
limitation varchar(500) comment '职业限制'
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='IT修真院职业表'
create table class
(
cid int auto_increment primary key comment '主键',
ctype varchar(10) not null comment '班级类型(线上或线下)',
cno int not null comment'班级编号',
snumber int comment '学员数量',
create_at bigint comment '创建时间',
update_at bigint comment '修改时间',
pid int comment '所属职业id',
monitor_id int comment '首席弟子id',
manifesto varchar(500) comment '班级宣言',
CONSTRAINT FK_CLASS_PID FOREIGN KEY (pid) REFERENCES profession(pid)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='IT修真院班级表'
create table user
(
uid int auto_increment primary key comment '主键',
uname varchar(50) not NULL comment '用户名',
password varchar(200) not null comment '密码',
phone_number bigint not null comment '手机号',
create_at bigint comment '注册时间',
update_at bigint comment '修改时间'
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='IT修真院用户表'
create table student
(
sid int auto_increment primary key comment '主键',
sno int comment '学号',
cid int not null comment '班级id',
uid int not null comment '用户id',
create_at bigint comment '入学时间',
update_at bigint comment '修改时间',
manifesto varchar(500) comment '入学宣言',
qq varchar(20) comment 'qq号',
CONSTRAINT FK_STUDENT_CID FOREIGN KEY(cid) REFERENCES class(cid),
CONSTRAINT FK_STUDENT_UID FOREIGN KEY(uid) REFERENCES user(uid)
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='IT修真院学生表'
2、pom.xml中加入jar包(备注:spring框架的其它包,在spring-webmvc都包含了,不用再引用)
测试:junit,spring框架:spring-webmvc、spring-test,mysql驱动 :mysql-connector-java、mybatis-spring,
连接池:c3p0,json解析器:org.codehaus.jackson的jackson-core-asl、jackson-core-lgpl、jackson-mapper-asl、jackson-mapper-lgpl,
日志:log4j、slf4j-api、slf4j-log4j12
环境:jstl、standard、javaee-api
tiles包:tiles-api、tiles-core、tiles-jsp、tiles-servlet、tiles-template
验证类:validation-api、hibernate-validator
httpclient:httpclient
3、配置web.xml.主要配置Spring应用上下文,Spring view分发器,log4j,工程编码过滤器
4、在src\main\java下添加包com.qing.tiles,在资源管理器中,在src\main\java\com\qing\tiles
文件夹下依次建立文件夹controller、dao、models.service、utils、web文件夹,
并在service文件夹下新建impl文件夹;在src\main\test下添加包com.qing.tiles.test,用来存放测试类
5、在src\main\resources下新建文件夹properties,文件夹下创建数据库连接配置文件db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/xztest4?useUnicode=true&characterEncoding=UTF-8
name=root
password=123
6、在src\main\resources下创建数据源连接池的的配置文件dataSource.xml
7、在src\main\resources下创建日志的的配置文件log4j.xml
8、在src\main\resources下创建spring上下文的的配置文件applicationContext.xml
9、在src\main\webapp\WEB-INF下创建dispatcher-servlet.xml文件
10、在src\main\webapp\WEB-INF下创建tiles-definitions.xml文件
11、在src\main\webapp\WEB-INF下创建文件夹views,再views下创建文件夹contents、layouts、navs、sections,test,分别存放内容页、模板页、导航页、网站头部和尾部页面、测试页面,将Task10和Task11中的静态页面分别拆分成内容、导航、头部、 尾部放入相应文件夹,并在layouts文件夹中编写模板页main.jsp
12、在src\main\webapp下创建resources文件夹,resource文件夹下创建css、images、scripts文件夹,分别存放css文件、图片和js文件
13、编辑tiles-definitions.xml文件,写入模板内容
14、创建user和student表所对应的实体类User和Student,注:继承于Serializable,可序列化;所有数据类型都用结构的,如各种32位以下的整数都弄成Integer,64位的整数为Long,double为Double,string为String;实现get/set方法,重写toString方法,实现默认无参构造函数和全字段构造函数
15、创建MyBatis的SQL映射文件UserMapper.xml、StudentMapper.xml
16、创建dao的接口文件UserMapper.java、StudentMapper.xml
17、创建service接口文件UserService.java、StudentService.java
18、创建service接口实现文件UserServiceImpl.java、StudentServiceImpl.java,备注:增删改要加注解@Transactional
19、创建工具类CookieUtil.java、DESUtil.java、MD5Util.java、Token.java
20、com.qing.tiles.web中创建拦截器LoginInterceptor.java,TokenInterceptor.java
21、创建控制层RegisterController.java、LoginContoller.java、HomeController.java、ProfessionController.java、RecommendController.java这几个类
22、测试:
注册失败,会出现提示信息
注册成功,跳转至登录页面
登录成功
点击退出
任务四:
1、自定义一个时间处理的Tag
操作步骤:
① 在utils包中创建一个处理标签的工具类JSTLTimeTag.java
② WEB-INF目录下建文件夹tld,文件夹下创建dateformat.tld文件,对标签处理类进行描述
③ 在web.xml中添加如下配置:
<!-- 自定义JSTL时间格式化 -->
<jsp-config>
<taglib>
<taglib-uri>http://java.sun.com/jsp/jstl/core</taglib-uri>
<taglib-location>/WEB-INF/tld/dateformat.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/datetag</taglib-uri> <!-- 注意这里的 '/datetag',下面就要用到 -->
<taglib-location>/WEB-INF/tld/dateformat.tld</taglib-location>
</taglib>
</jsp-config>
④ 在test包中新建一个控制器类DateController.java作为接口
⑤ 在views\test下新建jsp测试页面time.jsp,加入
<%@ taglib uri="/datetag" prefix="fmtDate"%>
<fmtDate:LongToDate parttern="yyyy-MM-dd HH:mm:ss" value="${time }"/>
⑥ 测试,输出正确的时间格式2016-06-22 10:45:36
知识总结:
① 自定义标签类继承TagSupport类,重写doStartTag方法,需要先把Long类型的时间转成String字符串, 然后再转成毫秒格式,毫秒是从格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总毫秒数,然后再通过SimpleDateFormat方法转成对应的时间格式
String vv = String.valueOf(value);
Calendar c=Calendar.getInstance();
SimpleDateFormat dateFormat=new SimpleDateFormat("yyyyMMddhhmmss");
long time = 0L;
try {
time = dateFormat.parse(vv).getTime();
} catch (java.text.ParseException e1) {
e1.printStackTrace();
}
c.setTimeInMillis(time);
dateFormat=new SimpleDateFormat(parttern);
String stime=dateFormat.format(c.getTime());
2、tiles标签的使用
操作步骤:
① dispatcher-servlet.xml文件中添加如下配置
<!-- 防止静态资源被拦截 -->
<mvc:resources mapping="/resouces/**" location="/resouces/"/>
<bean
id="tilesviewResolver"
class="org.springframework.web.servlet.view.tiles2.TilesViewResolver">
<property name="order" value="0"></property>
</bean>
<bean
id="tilesConfigurer"
class="org.springframework.web.servlet.view.tiles2.TilesConfigurer">
<property name="definitions">
<list>
<value>/WEB-INF/tiles-definitions.xml</value>
</list>
</property>
</bean>
② 在tiles-definitions.xml文件添加对模板的配置,控制器直接返回definition标签的name值就可以了
<definition name="home" extends="template-main">
<put-attribute name="nav-content" value="/WEB-INF/views/navs/nav_home.jsp" />
<put-attribute name="main-content" value="/WEB-INF/views/contents/home.jsp" />
</definition>
任务五:
1、使用MD5加盐对登录密码进行加密
操作步骤:
① 在utils包下创建工具类MD5Util.java
② 注册时将密码加密后再存入数据库
2、DES对用户ID和登录时间进行加密,放入Cookie
操作步骤:
① 在utils包下创建工具类DESUtil.java
② 登录时将用户ID和登录时间进行加密,放入Cookie
③ 创建工具类CookieUtil,判断用户是否登录,如果已经登录就从
loginToken中取出用户名,并进行DES解密,返回给调用页面
3、创建token拦截器,防止注册时重复提交
操作步骤
① 在util包下创建token注解类Token.java
② 在进入注册页面的方法上添加注解@Token(save=true),在注册方法上添加注解 @Token(remove=true)
③ dispatcher-servlet.xml文件中添加如下配置,拦截有关注册的页面
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/register/**"/>
<bean class="com.qing.tiles.web.TokenInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
④ 在web包下创建token拦截器类TokenInterceptor.java,在用户进入注册页面时生成一个唯一的token令牌, 存入session,用户点提交按钮后从session中移除token令牌,用户再次点提交按钮时,在session中查不到 token令牌,用户的请求就会被拦截.
⑤ 在注册方法中添加如下代码,便于测试
//让当前的线程睡眠3秒钟,模拟网络延迟而导致表单重复提交的现象
try {
Thread.sleep(3*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
⑥ 在注册出错时添加session:regFailure作为标注,在token拦截器中进行判断,防止请求被作为重复提交拦截, 判断完成后移除该session
知识总结:
① 表单重复提交有三种情况:
在网络延迟的情况下让用户有时间点击多次submit按钮导致表单重复提交
表单提交后用户点击【刷新】按钮导致表单重复提交
用户提交表单后,点击浏览器的【后退】按钮回退到表单页面后进行再次提交
备注:第一种情况可以通过js来解决,二三种情况就要在服务器端通过token解决了
参考链接:http://www.cnblogs.com/xdp-gacl/p/3859416.html
4、创建login拦截器,判断用户是否登录
① 给用户必须登录才能进入的页面的路径加前缀/u
② dispatcher-servlet.xml文件中添加如下配置,用户必须登录才能进入的页面
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/profession/u/**"/>
<bean class="com.qing.tiles.web.LoginInterceptor" />
</mvc:interceptor>
</mvc:interceptors>
③ 在utils包下创建login拦截器LoginInterceptor.java,查看Cookie中是否存在令牌loginToken,如果存在,说明用户已经登录,放行;如果不存在则跳转到登录页面
④ 退出登录时移除Cookie:loginToken
5、使用JSR-303进行用户注册的校验 @Valid
操作步骤:
① 准备校验时需要使用的Jar包
validation-api:JDK的接口;
hibernate-validator是对上述接口的实现;
② 编写需要校验的bean
@Min(value=6,message="密码不能小于6位")
private String password;
@NotBlank(message="手机号不能为空")
private Long phone_number;
③ 校验方法,备注:这里一个@Valid的参数后必须紧挨着一个BindingResult 参数,否则spring会在校验不通过时直接抛出异常
@Token(remove=true)
@RequestMapping(value="/validate",method=RequestMethod.POST)
public String save(@Valid User user,BindingResult result,Model model)
throws Exception{
//让当前的线程睡眠3秒钟,模拟网络延迟而导致表单重复提交的现象
try {
Thread.sleep(3*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
if (!result.hasErrors()) {
model.addAttribute("phone",user.getPhone_number());
String password=MD5Util.generate(user.getPassword());
user.setPassword(password);
userService.save(user);
return "login";
}
else {
System.out.println("出错了!");
for (FieldError error:result.getFieldErrors()) {
System.out.println(error.getField()+":"+error.getDefaultMessage());
}
return "register";
}
} catch (Exception e) {
throw e;
}
}
④ 页面显示
<form:errors path="phone_number" />
<form:errors path="password" />
知识总结:
① JSR303定义的校验类型
空检查
@Null 验证对象是否为null
@NotNull 验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty 检查约束元素是否为NULL或者是EMPTY.
备注: @NotEmpty、@NotBlank、@NotNull的区别:
@NotEmpty 用在集合类上面,@NotBlank 用在String上面,@NotNull用在基本类型上
Booelan检查
@AssertTrue 验证 Boolean 对象是否为 true
@AssertFalse 验证 Boolean 对象是否为 false
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
@Length(min=, max=) Validates that the annotated string is between min and max included.
日期检查
@Past 验证 Date 和 Calendar 对象是否在当前时间之前
@Future 验证 Date 和 Calendar 对象是否在当前时间之后
@Pattern 验证 String 对象是否符合正则表达式的规则
数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null
@Min 验证 Number 和 String 对象是否大等于指定的值
@Max 验证 Number 和 String 对象是否小等于指定的值
@DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
@DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
@Digits 验证 Number 和 String 的构成是否合法
@Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
@Range(min=, max=) Checks whether the annotated value lies between (inclusive) the specified minimum and maximum.
@Range(min=10000,max=50000,message="range.bean.wage")
private BigDecimal wage;
@Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
@CreditCardNumber信用卡验证
@Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。
@ScriptAssert(lang= ,script=, alias=)
@URL(protocol=,host=, port=,regexp=, flags=)
参考链接: http://my.oschina.net/u/2429470/blog/498197
http://exceptioneye.iteye.com/blog/1305040
终于补完了!
评论