web开发
原型设计服务:墨刀网**
Java Web知识体系大纲
[TOC]
0 前言
1 JAVA WEB
1.1 http协议
1.2 servlet技术
1.3 会话技术(Cookie&Session)
1.3.1 客户端会话技术
1.3.2 服务器端会话技术
1.4 jsp技术
1.4.1 jsp技术基础
1.4.1.1 jsp原理
1.4.1.2 jsp指令
1.4.1.3 jsp脚本片段
1.4.1.4 jsp表达式
1.4.2 el表达式
el表达式(expression language,el),
- 可以轻松访问存放在域对象中的bean对象及属性
- 结合JSTL,可以轻松访问集合中的元素
- 可以做简单的逻辑判断
- 调用java方法
1.4.2.1 读取数据
- 读取基本数据类型
<%-- 存放基本数据类型到request域--%>
<%
String data="abcd";
request.setAttribute("data",data);
%>
<%-- 使用el从request中取得数据--%>
存放的数据是:${data}
- 读取对象类型
①简单对象
<%--
存放对象类型数据类型到request域
Person类:
-String:name
—int:age
--%>
<%
Person p = new Person();
request.setAttribute("person",p);
%>
<%-- 使用el从request中取得数据--%>
存放person对象及其属性:${person.name} ${person.age}
②复杂对象:存在对象聚合
<%--
存放复杂对象类型数据类型到request域
Address类:
—String: city
—String: province
Person类:
-String:name
—int:age
-Address:address
--%>
<%
Person p = new Person();
p.setName("lr");
p.setAge(24);
Address a = new Address();
a.setProvince("Shanghai"); // 创建地址
p.setAddress(a); // 地址赋值给person
request.setAttribute("person",p);
%>
<%-- 使用el从request中取得数据--%>
存放person对象及其属性: ${person.name} ${person.age}
${person.address.province}
${person.address.city}
- 读取List集合
<%
List list = new ArrayList();
list.add(new Person("john"));
list.add(new Person("peter"));
list.add(new Person("andrew"));
request.setAttribute("list",list);
%>
<%-- 使用el从request中取得数据--%>
${list[0].name} ${list[1].name}
- 读取Map集合
<%
Map map = new HashMap();
map.put("aa",new Person("john"));
map.put("bb",new Person("andrew"));
map.put("cc",new Person("peter"));
map.put("111",new Person("lucy"));
request.setAttribute("m",map);
%>
<%-- 使用el从request中取得数据--%>
${map["aa"].name} ${map["bb"].name} ${map["cc"].name}
${map.aa.name} ${map.bb.name} ${map.cc.name}
<!-- 如果关键字是数字开头,必须用下面写发-->
<!-- 使用el表达式取数据时候,通常用.号,如果.号取不出来,则用[]号 -->
${map["111"].name}
- 访问指定域对象的数据及其他web对象
${pageScope.user.name}
${requesetScope.user.name}
${sessionScoope.user.name}
${applicationScope.user.name}
<%-- 获取客户端请求参数,param是一个Map对象,--%>
<%--其中每个请求参数给定一个值 --%>
<%-- http://localhost:8080/login.jsp?username=aa & password=123 --%>
${param}
${param.username} ${param.password}
<%-- 获取客户端请求参数,paramValues是一个Map对象,--%>
<%-- 其中每个请求参数给定多个值 --%>
<%-- http://localhost:8080/login.jsp?username=liuyun & username=rongbo --%>
${paramValues}
${paramValues.username[0]}
${paramValues.username[1]}
${header}
${header.Host} ${header['Accept-Language']}
${headerValues}
<%--cookie对象是一个Map对象,存放的是‘关键字映射到Cookie对象’的entry --%>
${cookie} <%-- Map对象 --%>
${cookie.JSESSIONID.name}
${cookie.JSESSIONID.vlaue}
<%--web.xml中配置了参数 --%>
<%--
<context-param>
<param-name>db</param-name>
<param-value>url-db</param-value>
</context-param>
--%>
${initParam}
${initParam.db}
1.4.2.2 逻辑判断
<%--完成数据回显,大量使用二元表达式--%>
<%--radio表单回显--%>
<%
request.setAttribute("gender", "male");
%>
<input type="radio" name="gender" value="male" checked=${gender=='male'?'checked':''}/>
<input type="radio" name="gender" value="female" checked=${gender=='female'?'checked':''} />
<%--checkbox表单回显--%>
<%--判断list集合是否为空--%>
${empty(list)}
1.4.2.3 *调用java代码
1.4.3 jsp标签库JSTL
- 导包:jstl standard
使用jsp指令,导入jstl的uri,并指定前缀: <%@taglib uri=”#” prefix=”c”/>
: 进入standard.jar->meta-inf: c.tld文件中,描述表述库文件
<%@taglib uri="#" prefix="c"/>
<%------------------------------------------------------%>
<%--迭代map集合中的数据--%>
<%------------------------------------------------------%>
<%
List list = new ArrayList();
list.add(new Person("john"));
list.add(new Person("peter"));
list.add(new Person("andrew"));
request.setAttribute("list",list);
%>
<c:forEach var="person" items="${list}">
${person.name};
</c:forEach>
<%------------------------------------------------------%>
<%--迭代map集合中的数据--%>
<%------------------------------------------------------%>
<%
Map map = new HashMap();
map.put("aa",new Person("john"));
map.put("bb",new Person("andrew"));
map.put("cc",new Person("peter"));
map.put("111",new Person("lucy"));
request.setAttribute("m",map);
%>
<%-- 对Map集合,本质上是对Map.entrySet放回的集合进行迭代--%>
<c:forEach item="entry" items="${map}">
${entry.key}:${entry.value.name}
</c:forEach>
<%------------------------------------------------------%>
<%--测试条件是否成立--%>
<%------------------------------------------------------%>
<c:if test="${user!=null}">
欢迎您${user.username}
</c:if>
<c:if test="${user==null}">
<input type="text" name="username"/>
<input type="password" name="password"/>
<input type="submit" value="登录"/>
</c:if>
1.4.4 jsp自定义标签库
1.5 WEB开发模式
1.5.1 Model1(Jsp+JavaBean)
1.5.2 Model2(JSP+Servlet+JavaBean)
1.5.3 WEB三层架构
1.5.3.1 概述
1.5.3.2 web层
web三层架构充分借鉴了MVC设计模式,优化程序结构,其中web层包括了:
- web层控制器servlet,控制器servlet调用业务逻辑层代码完成业务逻辑,不同的业务有不同的控制器
- web层控制jsp的servlet,通过接受客户端请求,同利用请求转发技术到jsp页面,从而返回web页面
- web层还包括web层工具类,负责从request请求中获得参数数据,
1.5.3.2.1 隐藏jsp的servlet
1.5.3.2.2 控制器servlet
1.5.3.3 service层
1.5.3.4 dao层
1.5.4 “MVC设计模式”和“WEB三层架构”之概念浅析
1.5.5 “前台、后台”和“前端、后端”概念浅析
2 SSH&SSM
2.1 概述
2.1 Struts2
2.2 Hibernates
2.3 Spring4
2.4 springMVC
2.5 MyBaits
2.6 SSH框架整合(Struts2+Spring+Hibernate)
2.7 SSM框架整合(Struts2+SpringMVC+MyBaits)
3 MySql
3.1 安装和配置
3.1.1 安装
Latin1是ISO-8859-1的别名,有些环境下写作Latin-1。ISO-8859-1编码是单字节编码,向下兼容ASCII,其编码范围是0x00-0xFF,0x00-0x7F之间完全和ASCII一致,0x80-0x9F之间是控制字符,0xA0-0xFF之间是文字符号。
3.1.2 配置
3.2 SQL语言
3.2.1 DDL
3.2.1.1 库操作
- 创建库
/*
* CREATE DATABASE [IF NOT EXISTS] db_name [[create_specification]
* [,create_specification]...]
* create_specification:
* [DEFAULT] CHARACTER SET charset_name | [DEFAULT] COLLATE collation_name
*/
create database mydb1;
create database mydb2 character set utf8; -- 指定字符集,utf8, 不是utf-8
create database mydb2 character set utf8 collate utf8_general_ci; --指定字符集、排序规则
show create database mydb2; --查看创建库的细节
- 删除库
drop database mydb1;
- 修改库
/*
/*
* CREATE DATABASE [IF NOT EXIST] db_name [[alter_specification]
* [,alter_specification]...]
* alter_specification:
* [DEFAULT] CHARACTER SET charset_name | [DEFAULT] COLLATE collation_name
* 注意:不能修改库名
*/
alter database mydb2 character set utf8;
show create database mydb2;
- 备份库
mysqldump -u 用户名 -p 数据库名 > 文件名.sql (windows命令)
- 恢复库
第一种方法
/**
* source 文件名.sql
*/
create database tt;
user tt;
create table a{
name varchar(20)
};
insert into a(name) values('aaaa');
select * from a;
mysql -u root -p tt > c:tt.sql (window命令 导出)
drop dababase tt; --删除库
--恢复库,只能恢复数据,不能恢复库,因此必须重新新建库
--1.创建库
create database tt; --建库
user tt; --进入库tt
source c:\a.sql; --恢复数据
第二种方法
mysql -uroot -proot tt<c:a.sql (windows命令)
3.2.1.2 表操作
- 创建表
/* CREATE TABLE table_name
* {
* field1 datatype,
* filed2 datatype,
* filed3 datatype
* }character set charset_name collate collation_name;
*
* datatype:
* 文本、二进制:
* char(size) ------定长
* varchar(size) ------变长
* blob(最大64k) longblob -----变长
* text longtext -----变长,大文本
* 日期时间:date datetime timestamp -----变长
* 注意:实际开发过程中,容量很大的数据(比如音频、视频等)不会存放到数据库中,而是存放到文件系统。
* 原因:解决数据库链接资源。读取超大容量数据,连接占用的时间长。
*/
create table employee
{
id int,
name varchar(40),
sex varchar(4),
entry_date date,
job varchar(40),
salary decimal(8,2),
resume text
};
show tables; ----查看所有表
show create table employee;----显示指定表的创建细节
desc employee ; ----查看表结构
- 修改表
/*
* 1.修改表:增加列、修改列数据类型、删除列、修改列名
* ALTER TABLE table_name
* ADD column datatype [default_expr] [,column datatype]...;
* MODIFY column datatype [default_expr] [,column datatype]...;
* DTOP column;
* CHANGE COLUMN old_name new_name data_type;
* 2. 修改表名
* RENAME TABLE table_name to table_name_1
*
* 3. 修改表的字符集
* ALTER TABLE table_name character set utf8
*
* 4. 删除表
* DROP TABLE table_name;
*/
alter table employee add image blob;----增加大头贴列,存放大头贴图片
alter table employee modify job varchar(60);----修改job列
alter table employee drop sex;----删除类
rename table employee; ----重新命名表(库不能重命名,但是表可以)
alter table employee character utf8;----修改字符集
alter table employee change column name username varchar(30);----修改列名
- 删除表
drop table employee;----删除表
3.2.2 DML(crud之cud操作)
crud: crete read update delete
- insert(create)
/**
* INSERT INTO tb_name[(filed1[, field2...])]
* VALUES(value [,value...]);
*
* 细节:1. 表名后面的字段列表可以不跟,这种情况下,values必须按顺序指定每个字段的值
* 2. 字符和日期必须被单引号''包含
* 3. 插入空值:不指定值,或者指定为null
* 4. insert into user(id) values(4)和insert into user(id) values('4')
* 因此,所有的数值类型的值可以加单引号,mysql可以自动转换为相应类型的值
*/
RENAME TABLE employee to user;
----注意没有TABLE关键字
insert into user(id, username,birthday, entry_date, job, salary,resume)
values(1, 'andrew','2014-03-33','bb','2019-06-32',90,'aaaa');
- update
/**
* UPDATE tb_name
* SET col_name1=expr1 [,col_name2=expr2...]
* [WHERE where_definition]
*/
update employee set salary=3000 where name='张三';
update employee set salary=1000,job='ccc' where name='andrew';
- delete
/**
* DELETE from tb_name
* [WHERE where_definition]
* 注意:
* 1.delete只能以记录为单位删除;
* 2.从一个表中删除记录将引起其他表的参照完整性问题。在修改数据库中的数据时,
* 头脑中应时刻不要忘记这个潜在的问题
*/
delete from employee where name="andrew";
delete from employee; ----删除所有记录
truncate table employee; ----摧毁表,并重新构建表结构,速度快,在要删除所有数据记录的情形下
3.2.3 DQL(crud之r)
select(read),包括:select子句、where子句、from子句、order by子句、group by子句、having子句
使用source命令导入sql脚本
/**
* SELECT [DISTINCT] *[column1 [,column2...]] FROM tb_name;
*/
----@file:定义sql脚本:c:\student.sql(可以是其他目录)
create table student
{
id int,
name varchar(20),
chinese float,
english float,
math float
};
insert into student(id,name,chinese,english,math) values('1','andrew','22','90','97');
insert into student(id,name,chinese,english,math) values('2','peter','100','90','97');
insert into student(id,name,chinese,english,math) values('3','lily','67','90','97');
insert into student(id,name,chinese,english,math) values('4','lucy','33','90','97');
----在客户端,使用: source c:\student.sql
----查询
select * from student; ----查询所有
select name,english from student; ----查询感兴趣的字段
select distinct english from student; ----剔除重复数据
在select子句中使用表达式
/**
* SELECT * {column1 | expression, column2 | expression,...}
* FROM tabble;
*
* SELECT column as 别名 from table;
*/
select name,(chinese+english+math) from student; ----计算总分
select name as 姓名,(chinese+english+math) as 分数 from student; ----添加别名
select name 姓名,(chinese+english+math) 分数 from student; ----添加别名
select * from student where english>'90';
select * from student where name='andrew';
select * from student where (chinese+english+math)>'200';
where子句中使用运算符
/**
* 在where子句中使用运算符
* 1.比较运算:
* > >= < <= = <>
* BETWEEN ... AND ...
* IN(set)
* LIKE 'pattern' ,这里使用两种通配符,%匹配一个或者多个字符,_匹配单个字符
* IS NULL
* 2.逻辑运算:
* and
* or
* not
*/
select * from student where english>'80' and english<'90';----(80,90)
select * from student where english between '80' and '90'; ----[80,90]
select * from student where math in(80,90);
select * from student where math='80' or math='90';
select * from student where name like '李%';
select * from student where math>'80' and chinese>'80';
使用order by子句排序
/**
* 使用order by 子句
*
* SELECT column1,column2...
* FROM tabble
* ORDER BY column ASC|DESC;
*/
select name,math from student order by math desc;
select name, (chinese+english+math) as score from student order by score desc;
使用聚合函数
/**
* 使用聚合函数:count,sum, avg, max, min
* SELECT count(*) | count(列名)
* FROM table
* [WHERE where_definition];
*/
select count(*) from student; ----count聚合函数只会统计有值的数据
select sum(english), sum(math) from student;
select sum(english)/sum(*) from student;
select avg(math) from student;
使用group by子句
select product, sum(price) from orders group by product;
使用having子句: 类似于where子句,但是where子句后不能跟聚合函数,但是having可以
select product from orders group by product having sum(product)>'100';
4 web开发典型业务逻辑
4.1 注册登录
使用mvc设计模式,结合web三层架构思想,开发注册、登录模块。具体到项目代码包组织如下:
domain
dao
service
web
——web.ui:hide jsp pages for users
——web.controller:calling service layer
——web.formbean: from jsp pages to controller
utils
Title:用户注册\n业务流程
浏览器->web.UI.\nRegisterUiServlet:访问注册页面\nregister.jsp
web.UI.\nRegisterUiServlet->register.jsp:forward到\n/WEB-INF/jsp/register.jsp
register.jsp->浏览器:返回register.jsp\n生成的注册页面
浏览器->RegisterServlet:用户填写表单,\n提交到RegisterServlet
RegisterServlet->WebUtils:封装request\n请求参数到Bean
WebUtils->WebUtils:调用BeanUtils.\ncopyProperty\n(destBean,key,value);
WebUtils->RegisterServlet:返回FormBean
RegisterServlet->RegisterServlet:form .\nvalidate
RegisterServlet->WebUtils:调用BeanUtils.\ncopyBean\n(key,value);
WebUtils->RegisterServlet:返回User \ndomain对象
RegisterServlet->BusinesService\nServlet:注册
BusinesService\nServlet->BusinesService\nServlet:1.检查用户\n是否存在\n2.不存在\则注册\n3.存在\n返回错误信息
BusinesService\nServlet->浏览器:返回login.jsp\n生成的登录页面
4.3 验证码
4.4 购物车
/**
* 数据库,
* 1. 使用Map集合模拟数据库;
* 2. 初始数据通过静态代码块添加到内存中Map集合
*/
package cn.itcast.DB;
import java.util.LinkedHashMap;
import java.util.Map;
import cn.itcast.domain.Book;
public class DB {
private static Map map = new LinkedHashMap<String,Book>();
static{
map.put("1", new Book("1","java","lr","itcast",33.3f));
map.put("2", new Book("2","php","lr","itcast",33.3f));
map.put("3", new Book("3","spring","lr","itcast",33.3f));
map.put("4", new Book("4","struts","lr","itcast",33.3f));
map.put("5", new Book("5","hibernate","lr","itcast",33.3f));
}
public static Map getAll(){
return map;
}
}
/**
* DAO层:
*/
import java.util.LinkedHashMap;
import java.util.Map;
import cn.itcast.DB.DB;
import cn.itcast.domain.Book;
public class BookDao {
public Map getAll(){
return DB.getAll();
}
public Book find(String id){
return (Book) DB.getAll().get(id);
}
}
/**
* 实体类:包括Book、Cart、CartItem
*/
package cn.itcast.domain;
public class Book {
String id;
String name;
String author;
String description;
float price;
public Book(String id, String name, String author, String description,float price) {
super();
this.id = id;
this.name = name;
this.author = author;
this.description = description;
this.price = price;
}
/* 此处省略getters和setters方法
}
package cn.itcast.domain;
public class CartItem {
private Book book;
int quantity;
float price;
}
package cn.itcast.domain;
import java.util.LinkedHashMap;
import java.util.Map;
public class Cart {
private Map<String, CartItem> map = new LinkedHashMap();
private float price;
public void add(Book book){
CartItem item = map.get(book.getId());
if(item == null){
item = new CartItem();
item.setBook(book);
item.setQuantity(1);
map.put(book.getId(), item);
}else{
item.setQuantity(item.getQuantity()+1);
}
}
public Map<String, CartItem> getMap() {
return map;
}
public void setMap(Map<String, CartItem> map) {
this.map = map;
}
public float getPrice() {
float totalPrice = 0.0f;
for(Map.Entry<String, CartItem> entry: map.entrySet()){
totalPrice += entry.getValue().getPrice();
}
this.price = totalPrice;
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
/**
* 业务逻辑层:
*/
package cn.itcast.serviceimpl;
import java.util.Map;
import cn.itcast.daoimpl.BookDao;
import cn.itcast.domain.Book;
import cn.itcast.domain.Cart;
public class BusinessService {
BookDao dao = new BookDao();
public Map getAll(){
return dao.getAll();
}
public Book find(String id){
return dao.find(id);
}
public void deleteCartItem(String id, Cart cart) {
// TODO Auto-generated method stub
cart.getMap().remove(id);
}
public void clearCart(Cart cart) {
// TODO Auto-generated method stub
cart.getMap().clear();
}
public void changeItemQuantity(String id, int quantity, Cart cart) {
// TODO Auto-generated method stub
cart.getMap().get(id).setQuantity(quantity);
}
}
/**
* web层——控制器servlet
* @brief:
* 1. web层控制器是页面请求的web资源,控制器调用逻辑层进行处理,将处理结果结果转发到jsp;
* 2. 转发到的jsp中,使用jstl、el表达式将数据从域中取出来用于显示;
* 3. jsp页面中的javascript代码和用户交互,根据结果动态请求其他web资源
* 包括的Servlet:
* ListBookServlet 对应‘浏览商品’链接访问的资源
* BuyServlet 对应‘购买’链接对应的资源
* ChangeQuantityServlet 对应‘数量input组件’对应的请求的资源
* DeleteCartItemServlet 对应‘删除’链接对应的资源
* ClearCartServlet 对应‘清空购物车’链接对应的资源
*/
// 具体servlet类省略
<%-- 浏览商品页面 --%>
<h1>书籍列表</h1>
<table border="1" width="70%" align="center">
<tr>
<td>书名</td>
<td>作者</td>
<td>简介</td>
<td>价格</td>
<td>操作</td>
</tr>
<c:forEach var="entry" items="${map }">
<tr>
<td>${entry.value.name }</td>
<td>${entry.value.author }</td>
<td>${entry.value.description }</td>
<td>${entry.value.price }</td>
<td>
<a href="${pageContext.request.contextPath }/BuyServlet?id=${entry.value.id }" target="_blank">购买</a>
</td>
</tr><br/>
</c:forEach>
</table>
<%--购物车页面--%>
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!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>
<script type="text/javascript">
function deleteItem(id){
var b = window.confirm("您确定删除吗?");
if(b){
window.location.href=href="${pageContext.request.contextPath }/DeleteItemServlet?id="+id;
}
}
function clearcart(){
var b = window.confirm("您确定清空吗?");
if(b){
window.location.href="${pageContext.request.contextPath }/ClearCartServlet";
}
}
function changeQuantity(input, id, oldquantity){
var quantity = input.value;
if(isNaN(quantity)){
alert("请输入合法数字");
input.value = oldquantity;
return;
}
if(quantity < 0 || quantity != parseInt(quantity) ){
alert("请输入正整数");
input.value = oldquantity;
return;
}
var b = window.confirm(" 确认修改吗为"+quantity);
if(b){
window.location.href="${pageContext.request.contextPath}/ChangeQuantityServlet?id="+id+"&quantity="+quantity;
}
}
</script>
</head>
<body style="text-align:center;">
<h1>书籍列表</h1>
<c:if test="${empty(cart.map)}">
您没有购买任何商品
</c:if>
<c:if test="${!empty(cart.map)}">
<table border="1" width="70%" align="center">
<tr>
<td>书名</td>
<td>作者</td>
<td>单价</td>
<td>数量</td>
<td>小计</td>
<td>操作</td>
</tr>
<c:forEach var="entry" items="${cart.map }">
<tr>
<td>${entry.value.book.name }</td>
<td>${entry.value.book.author }</td>
<td>${entry.value.book.price }</td>
<td>
<input type="text" name="quantity" value="${entry.value.quantity }"
onchange="changeQuantity(this,${entry.key }, ${entry.value.quantity })"/>
</td>
<td>${entry.value.price }</td>
<td>
<a href="javascript:vid(0)" onclick="deleteItem(${entry.key})">删除</a>
</td>
</c:forEach>
<tr>
<td colspan="3">总价</td>
<td colspan="2">${cart.price}</td>
<td colspan="1">
<a href="javascript:vid(0)" onclick="clearcart()">清空</a>
</td>
</tr>
</table>
</c:if>
</body>
</html>
4.5 在线支付
附录
关键代码
1 DAO层:dom4j操作xml的工具类
/**
* 这里导报必须导入dom4j的document类
* @author lr
*
*/
public class XmlUtils {
private static String xmlPath = null;
static{
xmlPath = XmlUtils.class.getClassLoader().getResource("users.xml").getPath();
System.out.println(xmlPath);
}
public static Document getDocument() throws DocumentException{
SAXReader reader = new SAXReader();
Document document = reader.read(new File(xmlPath));
return document;
}
public static void write2Xml(Document document) throws IOException{
XMLWriter writer = new XMLWriter(
new FileWriter( xmlPath)
);
writer.write( document );
writer.close();
}
}
2 Service层:生成md5码
/**
* 1.使用消息摘要算法生成md5码,然后使用base64算法编码
* 2.md5码生成采用消息摘要算法类 MessageDigest
* 3.生成base64码,采用 Base64
*/
public class ServiceUtils {
public static String md5(String data){
try {
MessageDigest md = MessageDigest.getInstance("md5");
byte[] md5 = md.digest(data.getBytes());
/*
* md5摘要太长,采用base64进行编码
* 1.使用BASE64Encoder,but jdk not support this deprecated class and method
* 2.使用Base64来获得Encoder
*/
Base64.Encoder encoder = Base64.getEncoder();
return encoder.encodeToString(md5);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
3 Web层:request中的form表单数据封装到formbean;frombean->domain bean
/**
* @method:public static <T> T request2Bean(HttpServletRequest request, Class<T> cls)
* @brief:
* 第一个关键点;将request中的property拷贝到bean中去,要使用到beanutils包中的静态方法,拷贝特定属性
* <T>是类型参数的形式参数,调用过程中类型通过T传入
* @author lr
*
* 关键点:使用BeanUtils的copyProperties时,之能拷贝bean里面的基本数据类型,要将form中的String日期
* 拷贝到Domain bean的Date属性中去,必须要写转换器
* ConvertUtils.register(Converter c,Class cls)
*/
public class WebUtils {
public static <T> T request2Bean(HttpServletRequest request, Class<T> cls) {
// 1.create an T instance
T bean;
try {
bean = cls.newInstance();
// 2. copy propertys in request to new bean
Enumeration<String> e = request.getParameterNames();
while(e.hasMoreElements()){
String name = e.nextElement();
String value = request.getParameter(name);
BeanUtils.copyProperty(bean, name,value);
}
} catch (Exception e) {
throw new RuntimeException();
}
return bean;
}
public static String generatieID(){
return UUID.randomUUID().toString();
}
public static void copyBean(Object src, Object dest){
ConvertUtils.register(new Converter() {
public Object convert(Class type, Object value) {
// TODO Auto-generated method stub
if(value==null){
return null;
}
String str = (String)value;
if(str.equals(""))
return null;
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(str);
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
}, Date.class);
try {
BeanUtils.copyProperties(dest, src);
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
}
4 使用dom4j搜索xml节点的关键用法
/**
* xpath常见模式:
* 1.查找属性值为指定值的user节点:
* "//user[@username='"+username+"' and @password='"+password+"']" 用户名、密码为指定值
* "//user[@username='"+username+"']" 用户名为指定值
*/
public class UserDaoImpl {
public void add(User user){
try {
Document document = XmlUtils.getDocument();
/*
* get the root element
*/
Element root = document.getRootElement();
Element e = root.addElement("user");
e.setAttributeValue("id",user.getId());
e.setAttributeValue("username", user.getUsername());
e.setAttributeValue("password", user.getPassword());
e.setAttributeValue("birthday", user.getBirthday() == null?"":user.getBirthday().toLocaleString());
XmlUtils.write2Xml(document);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/*
* find user according to specified usenrmae and password
*/
public User find(String username, String password){
User user = null;
try {
Document document = XmlUtils.getDocument();
Element e = (Element)document.selectSingleNode(
"//user[@username='"+username+"' and @password='"+password+"']");
if(e == null)
return null;
user = new User();
user.setId(e.attributeValue("id"));
user.setUsername(e.attributeValue("username"));
user.setPassword(e.attributeValue("password"));
user.setEmail(e.attributeValue("email"));
user.setBirthday(new Date());
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return user;
}
/*
* find if user exist
*/
public boolean find(String username){
try {
Document document = XmlUtils.getDocument();
Element e = (Element)document.selectSingleNode("//user[@username='"+username+"']");
if(e == null)
return false;
} catch (DocumentException e) {
// TODO Auto-generated cach block
e.printStackTrace();
}
return true;
}
}
5 formbean中的验证算法(正则表达式)
/**
* 正则表达式的\w在java字符串中,写成\\w;
* 典型的模式:
* 1.邮箱:"\\w+@\\w+(\\.\\w+)+",其中\\w表示字母、数字、下划线,例如lr@whu.edu.cn
* 2.用户名3-8个字母:"[a-zA-Z]{3,8}"
* 3.密码3-8位字母:"\\d{3,8}"
*
*/
public boolean validate(){
boolean isOK =true;
/*
* username
* 不允许为空,因此必须加trim,因为""和" "是等同,因此用trim修剪空格
*/
if(this.username == null || this.username.trim().equals("")){
isOK = false;
errs.put("username", "username can not be empty");
}else{
if(!username.matches("[a-zA-Z]{3,8}")){
isOK = false;
errs.put("username", "用户名必须是3-8位字母");
}
}
/*
* password
* 不允许为空,因此必须加trim,因为""和" "是等同,因此用trim修剪空格
*/
if(this.password == null || this.password.trim().equals("")){
isOK = false;
errs.put("password", "password can not be empty");
}else{
if(!password.matches("\\d{3,8}")){
isOK = false;
errs.put("password", "password must be 3-8 digits");
}
}
/*
* password2
* 不允许为空,因此必须加trim,因为""和" "是等同,因此用trim修剪空格
*/
if(this.password2 == null || this.password2.trim().equals("")){
isOK = false;
errs.put("password2", "password2 can not be empty");
}else{
if(!password.equals(password2)){
isOK = false;
errs.put("password2", "password2 not equals passwords");
}
}
/*
* email
* 不允许为空,因此必须加trim,因为""和" "是等同,因此用trim修剪空格
*/
if(this.email == null || this.email.trim().equals("")){
isOK = false;
errs.put("email", "email can not be empty");
}else{
if(!email.matches("\\w+@\\w+(\\.\\w+)+")){
isOK = false;
errs.put("email", "not the correct email format");
}
}
/**
* birthday can be empty,but if not empty ,it must be al valid value
*/
if(!(this.birthday== null) && !this.birthday.trim().equals("")){
try{
DateLocaleConverter dlc = new DateLocaleConverter();
dlc.convert(this.birthday,"yyyy-MM-dd");
}catch(ConversionException e){
isOK = false;
errs.put("birthday", "format is invalid");
}
}
return isOK;
}
6 使用UUID生唯一ID
public static String generatieID(){
return UUID.randomUUID().toString();
}
7 String到Date的转换
/**
* birthday can be empty,but if not empty ,it must be al valid value
*
* DateLocaleConverter 和 SimpleDateFormat
*
* 1. 使用DateLocaleConverter,convert方法转换非法字符串抛出异常
* 2. 确定字符串表示的日前是合法日期前提下,可以使用SimpleDateFormat
*/
if(!(this.birthday== null) && !this.birthday.trim().equals("")){
try{
DateLocaleConverter dlc = new DateLocaleConverter();
// 利用convert方法抛异常的特性,验证参数合法性
dlc.convert(this.birthday,"yyyy-MM-dd");
}catch(ConversionException e){
isOK = false;
errs.put("birthday", "format is invalid");
}
}
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
try {
return df.parse(str); // parse字符串
} catch (Exception e) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
mysql客户端乱码问题
插入数据乱码
问题描述:数据库为采用utf8字符集,在客户端插入中文数据,显示插入错误
原因分析:客户端默认采用gb2312字符集,数据库采用的非gb2312,客户端输入发送给数据库
解决思路:告诉数据库客户端采用gb2312编码
myql>show variables like 'chara%'
mysql>set character_set_client=gb2312;
mysql>insert into employee(username) values('张三');
myql>select * from employee;
取出数据乱码
问题描述:数据库采用utf字符集,客户端正确插入了中文数据到表中,在客户端查询时输出为乱码
原因分析:数据库按照utf8查询到了数据,送到客户端,但是客户端以gb2312解析后显示
解决思路:要想查看时不乱码
myql>show variables like 'chara%';
myql>set character_set_results=gb2312;
myql>select * from employee;
配置客户端永久不显示乱码
修改安装目录下的my.ini文件,CLIENT SECTION部分的:default-character-set=gb2312
#修改配置文件
#修改安装目录下的my.ini文件,
#CLIENT SECTION部分的:default-character-set=utf8
#省略
# CLIENT SECTION
# ----------------------------------------------------------------------
#
# The following options will be read by MySQL client applications.
# Note that only client applications shipped by MySQL are guaranteed
# to read this section. If you want your own MySQL client program to
# honor these values, you need to specify it as an option during the
# MySQL client library initialization.
#
[client]
port=3306
[mysql]
default-character-set=utf8
# SERVER SECTION
# ----------------------------------------------------------------------
#
# The following options will be read by the MySQL Server. Make sure that
# you have installed the server correctly (see above) so it reads this
# file.
#
[mysqld]
# The TCP/IP Port the MySQL Server will listen on
port=3306
#Path to installation directory. All paths are usually resolved relative to this.
basedir="D:/Program Files (x86)/MySQL/MySQL Server 5.0/"
#Path to the database root
datadir="D:/Program Files (x86)/MySQL/MySQL Server 5.0/Data/"
# The default character set that will be used when a new schema or table is
# created and no character set is defined
default-character-set=utf8
#省略