项目开发 模块开发思路:
##登录功能
发送Ajax请求
-发送时机:登录按钮onclick
-请求参数:用户名和密码
-请求地址:/user/login.do
服务器端处理
/user/login.do
—>DispatcherServlet
—>HanlderMapping
—>UserLoginController.execute
—>UserService.checkLogin
—>UserDao—>cn_user(查询)
—>返回NoteResult
—>调用jackson包输出JSON结果
Ajax回调处理
=====================
任务一:重新构建cloud_note项目,
实现UserDao.findByName
任务二:编写UserService组件,实现接口标准如下
public interface UserService{
public NoteResult checkLogin(
String name,String password);
}
NoteResult返回结果:
a.如果用户名错误,
返回status=1,msg=”用户名错误”,data=null
b.如果密码错误,
返回status=2,msg=”密码错误”,data=null
c.用户名密码正确
返回status=0,msg=”登录成功”,data=null
##注册功能实现
###发送Ajax请求
-请求发送时机:注册按钮的onclick
-请求参数:用户名,昵称,密码
-请求地址:/user/regist.do
###服务器端处理
/user/regist.do
-->DispatcherServlet
-->handlerMapping
-->UserRegistController.execute
-->UserService.registUser
-->UserDao-->cn_user(插入)
-->返回NoteResult
-->调用jackson包输出JSON结果
###Ajax回调处理
项目目录结构:
后台逻辑实现:
数据库连接配置:
spring-mybatis.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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<!-- DataSource -->
<bean id="dbcp" class="org.apache.commons.dbcp.BasicDataSource">
<property name="username" value="root"></property>
<property name="password" value="1234"></property>
<property name="url" value="jdbc:mysql://localhost:3306/cloud_note?useUnicode=true&characterEncoding=utf8"></property>
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
</bean>
<!-- SqlSessionFactoryBean -->
<bean id="ssf" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 指定dataSource -->
<property name="dataSource" ref="dbcp"></property>
<!-- 指定SQL定义文件 -->
<property name="mapperLocations"
value="classpath:mapper/*.xml">
</property>
</bean>
<!-- 定义MapperScannerConfigure
生成 的Dao对象id为接口名首字母小写-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定Mapper接口所在包 -->
<property name="basePackage" value="com.dk.cloudnote.dao">
</property>
<!-- 默认注入SqlSessionFactory,可以省略 -->
<property name="sqlSessionFactory" ref="ssf"></property>
</bean>
</beans>
组件扫描配置:
spring-mvc.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:jdbc="http://www.springframework.org/schema/jdbc"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd">
<!-- handlerMapping -->
<mvc:annotation-driven/>
<!-- 扫描Controller和Service组件对象 -->
<context:component-scan base-package="com.dk.cloudnote"/>
</beans>
实体类:
User.java
package com.dk.cloudnote.entity;
import java.io.Serializable;
public class User implements Serializable{
private String cn_user_id;
private String cn_user_name;
private String cn_user_password;
private String cn_user_token;
private String cn_user_nick;
public String getCn_user_id() {
return cn_user_id;
}
public void setCn_user_id(String cn_user_id) {
this.cn_user_id = cn_user_id;
}
public String getCn_user_name() {
return cn_user_name;
}
public void setCn_user_name(String cn_user_name) {
this.cn_user_name = cn_user_name;
}
public String getCn_user_password() {
return cn_user_password;
}
public void setCn_user_password(String cn_user_password) {
this.cn_user_password = cn_user_password;
}
public String getCn_user_token() {
return cn_user_token;
}
public void setCn_user_token(String cn_user_token) {
this.cn_user_token = cn_user_token;
}
public String getCn_user_nick() {
return cn_user_nick;
}
public void setCn_user_nick(String cn_user_nick) {
this.cn_user_nick = cn_user_nick;
}
}
实体映射配置:
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.dk.cloudnote.dao.UserDao">
<select id="findByName" parameterType="string"
resultType="com.dk.cloudnote.entity.User">
select * from cn_user
where cn_user_name=#{name}
</select>
<insert id="sava" parameterType="com.dk.cloudnote.entity.User">
insert into cn_user
(cn_user_id,cn_user_name,
cn_user_password,cn_user_nick)
values(#{cn_user_id},#{cn_user_name},
#{cn_user_password},#{cn_user_nick})
</insert>
</mapper>
映射Dao接口:
UserDao.java
package com.dk.cloudnote.dao;
import com.dk.cloudnote.entity.User;
public interface UserDao {
public void sava(User user);
public User findByName(String name);
}
UserDao接口方法测试:
TestUserDao.java
package com.dk.cloundnote.dao;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.dk.cloudnote.dao.UserDao;
import com.dk.cloudnote.entity.User;
public class TestUserDao {
@Test//测试UserDao
public void test2(){
String conf = "conf/spring-mybatis.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
UserDao dao = ac.getBean("userDao", UserDao.class);
User user = dao.findByName("demo");
if(user == null){
System.out.println("用户不存在");
}else{
System.out.println(user.getCn_user_password());
}
}
@Test//测试dbcp连接池
public void test1() throws SQLException{
String conf = "conf/spring-mybatis.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
DataSource ds = ac.getBean("dbcp", DataSource.class);
System.out.println(ds.getConnection());
}
}
测试运行UserDao方法后截图:
通用工具类:
NoteResult.java
package com.dk.cloudnote.util;
import java.io.Serializable;
/**
* 作为所以请求的响应对象
* @author Cher_du
*
*/
public class NoteResult implements Serializable{
private int status;//状态
private String msg;//提示消息
private Object data;//返回的数据
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
###MD5算法特点:
-可以将不等长字节信息转成等长字节信息
-不可逆算法操作,不能还原
-属于摘要算法,最初设计出来是用于校验文件完整性
NoteUtil.java
package com.dk.cloudnote.util;
import java.security.MessageDigest;
import java.util.UUID;
import org.apache.commons.codec.binary.Base64;
public class NoteUtil {
/**
* 采用UUID算法生成一个唯一性的字符串
* @return 主键值id
*/
public static String createId(){
UUID uuid = UUID.randomUUID();
String id = uuid.toString();
return id;
}
/**
* 将msg采用MD5算法处理,返回一个String结果
* @param msg 明文
* @return 密文
*/
public static String md5(String msg){
try{
MessageDigest md =
MessageDigest.getInstance("MD5");
//原始信息input
byte[] input = msg.getBytes();
//加密信息output
byte[] output = md.digest(input);//加密处理
//采用Base64将加密内容output转成String字符串
String s = Base64.encodeBase64String(output);
return s;
}catch(Exception ex){
System.out.println("md5加密失败");
return null;
}
}
public static void main(String[] args){
System.out.println(createId());
System.out.println(createId());
System.out.println(md5("123456"));
// System.out.println(md5("123456789ffasd"));
}
}
业务层代码:
接口接口部分:
UserService.java
package com.dk.cloudnote.service;
import com.dk.cloudnote.util.NoteResult;
public interface UserService {
public NoteResult registUser(String name,String nick,String password);
public NoteResult checkLogin(String name,String password);
}
业务实现部分:
UserServiceImpl.java
package com.dk.cloudnote.service;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.dk.cloudnote.dao.UserDao;
import com.dk.cloudnote.entity.User;
import com.dk.cloudnote.util.NoteResult;
import com.dk.cloudnote.util.NoteUtil;
@Service("userService")
public class UserServiceImpl implements UserService{
@Resource//注入
private UserDao userDao;
public NoteResult checkLogin(String name, String password) {
NoteResult result = new NoteResult();
User user = userDao.findByName(name);
//检测用户名
if(user == null){
result.setStatus(1);
result.setMsg("用户名错误");
// result.setData(null);
return result;
}
//检测密码
//将用户输入的明文加密
String md5Password = NoteUtil.md5(password);
//比对数据库中的密码
if(!user.getCn_user_password().equals(md5Password)){
result.setStatus(2);
result.setMsg("密码错误");
return result;
}
//用户名和密码正确
result.setStatus(0);
result.setMsg("登录成功");
//将用户身份ID返回
result.setData(user.getCn_user_id());
return result;
}
public NoteResult registUser(String name, String nick, String password) {
NoteResult result = new NoteResult();
//检测用户名是否存在
User has_user = userDao.findByName(name);
if(has_user != null){//已存在
result.setStatus(1);
result.setMsg("用户名已存在");
return result;
}
//执行注册逻辑
User user = new User();
//设置用户ID
String userId = NoteUtil.createId();
user.setCn_user_id(userId);
user.setCn_user_name(name);//设置用户名
user.setCn_user_nick(nick);//设置昵称
//密码加密,设置密码
String md5_password = NoteUtil.md5(password);
user.setCn_user_password(md5_password);
userDao.sava(user);//添加用户
result.setStatus(0);
result.setMsg("注册成功");
return result;
}
}
业务层功能 单元测试:
TestCheckLogin.java
package com.dk.cloundnote.service;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.dk.cloudnote.service.UserService;
import com.dk.cloudnote.util.NoteResult;
public class TestCheckLogin {
@Test
public void test1(){
String[] conf = {"conf/spring-mvc.xml",
"conf/spring-mybatis.xml"};
ApplicationContext ac= new ClassPathXmlApplicationContext(conf);
UserService service = ac.getBean("userService", UserService.class);
NoteResult result = service.checkLogin("test02","test02");
System.out.println(result.getStatus());
System.out.println(result.getMsg());
}
}
测试运行后:
TestRegistUser.java
package com.dk.cloundnote.service;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.dk.cloudnote.service.UserService;
import com.dk.cloudnote.util.NoteResult;
public class TestRegistUser {
@Test
public void test1(){
String[] conf = {"conf/spring-mvc.xml",
"conf/spring-mybatis.xml"};
ApplicationContext ac= new ClassPathXmlApplicationContext(conf);
UserService service = ac.getBean("userService", UserService.class);
NoteResult result = service.registUser("test02", "test02", "test02");
System.out.println(result.getStatus());
System.out.println(result.getMsg());
}
}
测试运行后:
控制层功能:
UserLoginController.java
package com.dk.cloudnote.controller.user;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.dk.cloudnote.service.UserService;
import com.dk.cloudnote.util.NoteResult;
@Controller//扫描
@RequestMapping("/user")
public class UserLoginController {
@Resource//注入
private UserService userService;
@RequestMapping("/login")
@ResponseBody
public NoteResult execute(String name,String password){
System.out.println("UserLoginController....");
NoteResult result = userService.checkLogin(name, password);
return result;
}
}
UserRegistController.java
package com.dk.cloudnote.controller.user;
import javax.annotation.Resource;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.dk.cloudnote.service.UserService;
import com.dk.cloudnote.util.NoteResult;
@Controller
@RequestMapping("/user")
public class UserRegistController {
@Resource
private UserService userService;
@RequestMapping("/regist.do")
@ResponseBody
public NoteResult execute(String name,String password,String nick){
System.out.println("UserRegistController....");
NoteResult result = userService.registUser(name, nick, password);
return result;
}
}
控制层测试:
浏览器录入:http://localhost:8088/cloud_note_learn/user/regist.do?name=test001&password=test001&nick=test001
页面测试结果:
浏览器录入:http://localhost:8088/cloud_note_learn/user/login.do?name=test001&password=test001
页面测试结果:
前端逻辑实现:
前端工程结构:
log_in.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="styles/login.css"/>
<script type="text/javascript"
src="scripts/jquery.min.js">
</script>
<script type="text/javascript"
src="scripts/cookie_util.js">
</script>
<script type="text/javascript"
src="scripts/login.js">
</script>
</head>
<body>
<div class="global">
<div class="log log_in" tabindex='-1' id='dl'>
<dl>
<dt>
<div class='header'>
<h3>登 录</h3>
</div>
</dt>
<dt></dt>
<dt>
<div class='letter'>
用户名: <input type="text" name="" id="count" tabindex='1'/>
<span id="count_span"></span>
</div>
</dt>
<dt>
<div class='letter'>
密 码: <input type="password" name="" id="password" tabindex='2'/>
<span id="password_span"></span>
</div>
</dt>
<dt>
<div>
<input type="button" name="" id="login" value=' 登 录 ' tabindex='3'/>
<input type="button" name="" id="sig_in" value=' 注 册 ' tabindex='4'/>
</div>
</dt>
</dl>
</div>
<div class="sig sig_out" tabindex='-1' id='zc' style='visibility:hidden;'>
<dl>
<dt>
<div class='header'>
<h3>注 册</h3>
</div>
</dt>
<dt></dt>
<dt>
<div class='letter'>
用户名: <input type="text" name="" id="regist_username" tabindex='5'/>
<div class='warning' id='warning_1'><span>该用户名不可用</span></div>
</div>
</dt>
<dt>
<div class='letter'>
昵 称: <input type="text" name="" id="nickname" tabindex='6'/>
</div>
</dt>
<dt>
<div class='letter'>
密 码: <input type="password" name="" id="regist_password" tabindex='7'/>
<div class='warning' id='warning_2'><span>密码长度过短</span></div>
</div>
</dt>
<dt>
<div class='password'>
确认密码: <input type="password" name="" id="final_password" tabindex='8'/>
<div class='warning' id='warning_3'><span>密码输入不一致</span></div>
</div>
</dt>
<dt>
<div>
<input type="button" name="" id="regist_button" value=' 注 册 ' tabindex='9'/>
<input type="button" name="" id="back" value=' 返 回 ' tabindex='10'/>
<script type="text/javascript">
function get(e){
return document.getElementById(e);
}
get('sig_in').onclick=function(){
get('dl').className='log log_out';
get('zc').className='sig sig_in';
}
get('back').onclick=function(){
get('zc').className='sig sig_out';
get('dl').className='log log_in';
}
window.onload=function(){
var t =setTimeout("get('zc').style.visibility='visible'",800);
get('final_password').onblur=function(){
var npassword=get('regist_password').value;
var fpassword=get('final_password').value;
if(npassword!=fpassword){
get('warning_3').style.display='block';
}
}
get('regist_password').onblur=function(){
var npassword=get('regist_password').value.length;
if(npassword<6&&npassword>0){
get('warning_2').style.display='block';
}
}
get('regist_password').onfocus=function(){
get('warning_2').style.display='none';
}
get('final_password').onfocus=function(){
get('warning_3').style.display='none';
}
}
</script>
</div>
</dt>
</dl>
</div>
</div>
</body>
</html>
前端事件文件结构:
登录事件、注册事件 的处理逻辑:
login.js
//注入口
$(function(){
//登录按钮处理
$("#login").click(login);
//按回车实现登录
$("body").keydown(function(event){
var code = event.keyCode;
if(code==13){//回车
login();//调用login函数
}
});
//注册按钮处理
$("#regist_button").click(regist);
});
//注册处理
function regist(){
//清空提示信息
$("#warning_1 span").html("");
$("#warning_2 span").html("");
$("#warning_3 span").html("");
$("#warning_1").hide();
$("#warning_2").hide();
$("#warning_3").hide();
//获取请求参数
var name =
$("#regist_username").val().trim();
var nick = $("#nickname").val().trim();
var password =
$("#regist_password").val().trim();
var final_password =
$("#final_password").val().trim();
//检查格式
var check = true;
if(name==""){
$("#warning_1 span").html("用户名为空");
$("#warning_1").show();
check = false;
}
if(password==""){
$("#warning_2 span").html("密码为空");
$("#warning_2").show();
check = false;
}else if(password.length<6){
$("#warning_2 span").html("密码大于等于6位");
$("#warning_2").show();
check = false;
}
if(final_password==""){
$("#warning_3 span").html("确认密码为空");
$("#warning_3").show();
check = false;
}else if(final_password!=password){
$("#warning_3 span").html("与密码不一致");
$("#warning_3").show();
check = false;
}
//发送Ajax请求
if(check){
$.ajax({
url:"http://localhost:8088/cloud_note_learn/user/regist.do",
type:"post",
data:{"name":name,"nick":nick,"password":password},
dataType:"json",
success:function(result){
if(result.status==0){//成功
//提示成功
alert(result.msg);
//切换到登录界面
$("#back").click();//触发单击操作
}else if(result.status==1){
//提示用户名已占用
$("#warning_1 span").html(result.msg);
$("#warning_1").show();
}
},
error:function(){
alert("注册发生异常");
}
});
}
};
//登录处理
function login(){
//清空提示信息
$("#count_span").html("");
$("#password_span").html("");
//获取请求参数
var name = $("#count").val().trim();
var password = $("#password").val().trim();
//检查参数格式
var check = true;//true通过检测;false未通过
if(name==""){
$("#count_span").html("用户名为空");
check = false;
}
if(password==""){
$("#password_span").html("密码为空");
check = false;
}
//发送Ajax请求
if(check){
$.ajax({
url:"http://localhost:8088/cloud_note_learn/user/login.do",
type:"post",
data:{"name":name,"password":password},
dataType:"json",
success:function(result){
if(result.status==0){//成功
//获取返回的用户ID,存入Cookie
var userId = result.data;
//调用cookie_util.js函数写入Cookie
addCookie("userId",userId,2);
window.location.href = "edit.html";
}else if(result.status==1){//用户名错误
$("#count_span").html(result.msg);
}else if(result.status==2){
$("#password_span").html(result.msg);
}
},
error:function(){
alert("发生登录异常");
}
});
}
};
前端功能测试:
1. 用户注册功能测试:
浏览器录入 http://localhost:8088/cloud_note_learn/log_in.html
点击 注册 按钮 后: