****项目介绍(无图)****
Java 实训项目–Estore图书商城
1、 项目介绍
1.1 课程名称:
Estore图书商城
1.2 课程持续时间:
三周
1.3 课程实施方式:
项目驱动式教学
1.4 课程实施对象:
计算机相关专业在校学生
1.5 实训意义与目标:
体验真实项目开发
通过商业化项目的开发和演示,让学生真正理解软件开发思想,了解行业主流的开发技术,了解从需求、设计、编码、测试等软件开发流程,使用企业中常用的开发工具,增强解决处理问题的能力,积累专业的开发经验。
理解专业技术标准
按照软件工程的要求,通过实际的行业项目,真正理解学校学习的开发语言,并提高编码的熟练度,熟悉各种项目开发文档和表格的撰写。
锻炼团队合作
培养学生高度的敬业精神、团队合作意识、协作能力,迅速有效缩短个人与企业实际需求的差距,从而实现从学校到企业的顺利过渡。
1.6 项目功能介绍:
这是一个购物类图书商城网站,面向所有网民开放,主要提供商品在线销售服务
服务端 使用服务器进行商品的发布
客户端 将服务器端发布的商品进行展示,供用户购买
2、 实训项目实施方案
项目任务分解:
实训任务1:掌握java基础
Tomcat的下载、安装以及使用
JSP页面的编写与使用
Servlet的使用与练习
MySql数据库的安装、基本操作
JDBC操作数据库
效果图如下:
图2-1-1 Navicat forMySql查看数据表
实训任务2: 掌握SSM框架
SSM框架的使用
SSM框架整合使用
图2-1-2 SSM框架整合
实训任务3: 图书商城服务端编写
对客户端显示的商品进行管理
图2-1-3商品发布页面
实训任务4:网站客户端编写
对服务端发布的商品进行展示
图2-1-4 图书商城首页
3、 实训项目软硬件环境配置要求
硬件环境配置
电脑一套(CPU主频不小于1.5GHz,内存空间不小于4GB,硬盘存储空间不小于60GB)
实训场地(30平米以上)
投影仪(如:明基,小帅影院,NEC,奥图码)
软件环境配置
Eclipse安装包
Tomcat安装包(可以用绿色版或安装版,版本不小于7.0)
My SQL数据库服务安装包(版本不小于5.0)
JDK安装包(版本不小于1.7)
浏览器(火狐或Google)
首先配置web.xml文件,如果创建的是maven程序不需要这一步
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>bookshopping</display-name>
<welcome-file-list>
<welcome-file>/</welcome-file>
</welcome-file-list>
<!-- servletContext:代表整个web应用 -->
<!-- spring监听器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- springmvc前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!-- springmvc对哪些请求解析
*.action 解析所有的以.action结尾的请求
/ 解析所有的请求,除了jsp,需要在springmvc配置文件中定义静态资源的访问
-->
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 验证码servlet -->
<servlet>
<servlet-name>checkImg</servlet-name>
<servlet-class>com.liuliuliu.utils.CheckImgServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>checkImg</servlet-name>
<url-pattern>/checkImg</url-pattern>
</servlet-mapping>
<!-- 字符编码的过滤器 -->
<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>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>TRUE</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encoding</filter-name>
<!-- 拦截所有的请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 自动登录的过滤器 -->
<filter>
<filter-name>autoLogin</filter-name>
<filter-class>com.feicui.filter.AutoLoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>autoLogin</filter-name>
<!-- 配置对哪些请求拦截 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
在写java web程序时jsp页面都已经给出,这里就不多加叙述了
接下来配置好springmvc文件
<?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-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">
<!-- 对于静态资源的访问 -->
<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
<mvc:resources location="/images/" mapping="/images/**"></mvc:resources>
<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
<mvc:resources location="/fonts/" mapping="/fonts/**"></mvc:resources>
<mvc:resources location="/img/" mapping="/img/**"></mvc:resources>
<mvc:resources location="/plugins/" mapping="/plugins/**"></mvc:resources>
<!-- 处理器适配器,处理器映射器 -->
<mvc:annotation-driven></mvc:annotation-driven>
<context:component-scan base-package="com.liuliuliu.controller"></context:component-scan>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 上传组件 -->
<bean name="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 设置上传文件的大小5M -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
</beans>
现在开始写代码部分
首先根据数据库建立好每个对象的模型,也就是model层
这里使用用户对象做说明
package com.liuliuliu.model;
/**
* 实体类:
* 1.属性私有化,提供公共的get和set方法
* 2.必须要有无参构造
* 3.属性类型应该为包装类类型
* 4.类不能使用final修饰
*
* final,finally,finalize
*
*/
public class Users {
private Integer id;
private String username;
private String password;
private String nickname;
private String email;
private String role;
private Integer state;
private String activecode;
private String updatetime;
public void setId(Integer id){
this.id = id;
}
public Integer getId(){
return id;
}
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;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
}
public String getActivecode() {
return activecode;
}
public void setActivecode(String activecode) {
this.activecode = activecode;
}
public String getUpdatetime() {
return updatetime;
}
public void setUpdatetime(String updatetime) {
this.updatetime = updatetime;
}
@Override
public String toString() {
return "Users [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname
+ ", email=" + email + ", role=" + role + ", state=" + state + ", activecode=" + activecode
+ ", updatetime=" + updatetime + "]";
}
}
接下来在dao层书写方法的接口,还是用user作实例
public interface UsersMapper {
/**
* 保存方法
* @param user 保存用户对象
* @return 如果返回1,保存成功,否则,返回0
*/
public int saveUsers(Users user);
/**
* 删除用户方法
* @param id 要删除的用户的id
* @return 如果返回1,删除成功,否则,返回0
*/
public int delUsers(int id);
/**
* 修改的方法
* @param user 要修改的对象
* @return 如果返回1,修改成功,否则,返回0
*/
public int updateUsers(Users user);
/**
* 根据id查询用户
* @param id 要查询的用户的id
* @return 查询的用户对象
*/
public Users findUserById(int id);
/**
* 查询所有的用户
* @return 所用用户组成的集合
*/
public List<Users> findUsersList();
/**
* 用户登录方法
* @param user 对象中存放用户输入的用户名和密码
* @return 登录成功,返回users对象,否则,返回null
*/
public Users login(Users user);
public Users findUserByCode(String code);
public Users findUserByName(String username);
}
在service层和serviceimpl层实现
public interface UsersService {
/**
* 保存方法
* @param user 保存用户对象
* @return 如果返回1,保存成功,否则,返回0
*/
public int saveUsers(Users user);
/**
* 删除用户方法
* @param id 要删除的用户的id
* @return 如果返回1,删除成功,否则,返回0
*/
public int delUsers(int id);
/**
* 修改的方法
* @param user 要修改的对象
* @return 如果返回1,修改成功,否则,返回0
*/
public int updateUsers(Users user);
/**
* 根据id查询用户
* @param id 要查询的用户的id
* @return 查询的用户对象
*/
public Users findUserById(int id);
/**
* 查询所有的用户
* @return 所用用户组成的集合
*/
public List<Users> findUsersList();
/**
* 用户登录方法
* @param user 对象中存放用户输入的用户名和密码
* @return 登录成功,返回users对象,否则,返回null
*/
public Users login(Users user);
/**
* 根据激活码查询用户
* @param code
* @return
*/
public Users findUserByCode(String code);
/**
* 根据用户名查询对象
* @param username 查询的用户名
* @return 查询的对象
*/
public Users findUserByName(String username);
}
@Service
public class UsersServiceImpl implements UsersService {
@Autowired
private UsersMapper usersMapper;
@Override
public int saveUsers(Users user) {
int num = usersMapper.saveUsers(user);
//发送给用户激活邮件
try {
MailUtils.sendMail(user.getEmail(), user.getActivecode());
} catch (Exception e) {
e.printStackTrace();
}
return num;
}
@Override
public int delUsers(int id) {
return usersMapper.delUsers(id);
}
@Override
public int updateUsers(Users user) {
return usersMapper.updateUsers(user);
}
@Override
public Users findUserById(int id) {
return usersMapper.findUserById(id);
}
@Override
public List<Users> findUsersList() {
return usersMapper.findUsersList();
}
@Override
public Users login(Users user) {
return usersMapper.login(user);
}
@Override
public Users findUserByCode(String code) {
return usersMapper.findUserByCode(code);
}
@Override
public Users findUserByName(String username) {
return usersMapper.findUserByName(username);
}
}
用mybatis做链接数据库的操作
<?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="com.feicui.dao.UsersMapper">
<!-- 插入 -->
<insert id="saveUsers" parameterType="com.feicui.model.Users">
insert into users(username,password,nickname,email,role,state,activecode,updatetime)
values(#{username},#{password},#{nickname},#{email},#{role},#{state},#{activecode},#{updatetime})
</insert>
<!-- 删除 -->
<delete id="delUsers" parameterType="int">
delete from users where id = #{id}
</delete>
<!-- 修改 -->
<update id="updateUsers" parameterType="com.feicui.model.Users">
update users set username = #{username},password = #{password},nickname = #{nickname},email = #{email},role = #{role},state = #{state}
where id = #{id}
</update>
<!-- 根据id查询 -->
<select id="findUserById" parameterType="int" resultType="com.feicui.model.Users">
select * from users where id = #{id}
</select>
<!-- 查询所有 -->
<select id="findUsersList" resultType="com.feicui.model.Users">
select * from users
</select>
<!-- 登录 -->
<select id="login" parameterType="com.feicui.model.Users" resultType="com.feicui.model.Users">
select * from users where username = #{username} and password = #{password}
</select>
<!-- 根据激活码查询用户 -->
<select id="findUserByCode" parameterType="string" resultType="com.feicui.model.Users">
select * from users where activecode = #{activecode}
</select>
<!-- 根据用户名查询对象 -->
<select id="findUserByName" parameterType="string" resultType="com.feicui.model.Users">
select * from users where username = #{name}
</select>
</mapper>
不要忘了配置数据库和事物管理器,在service中分别配置
<?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-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 引入外部的db.properties文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 数据库连接池 -->
<bean name = "dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 数据库连接信息 -->
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- sqlsessionFactory -->
<bean name = "sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="mapperLocations" value="classpath:mybatis/*.xml"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.feicui.dao"></property>
</bean>
</beans>
<?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:aop="http://www.springframework.org/schema/aop"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 扫描service中的注解 -->
<context:component-scan base-package="com.liuliuliu.service"></context:component-scan>
<!-- 事务管理 -->
<!-- 事务管理器 -->
<bean name = "transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 通知 -->
<tx:advice transaction-manager="transactionManager" id = "txAdvice">
<tx:attributes>
<!-- propagation:事务的传播行为 -->
<tx:method name="save*" propagation="REQUIRED" read-only="false"/>
<tx:method name="update*" propagation="REQUIRED" read-only="false"/>
<tx:method name="del*" propagation="REQUIRED" read-only="false"/>
<tx:method name="get*" propagation="SUPPORTS" read-only="true"/>
<tx:method name="add*" propagation="REQUIRED" read-only="false"/>
<tx:method name="edit*" propagation="REQUIRED" read-only="false"/>
<tx:method name="remove*" propagation="REQUIRED" read-only="false"/>
<tx:method name="find*" propagation="SUPPORTS" read-only="true"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut expression="execution(* com.liuliuliu.service.impl.*.*(..))" id="pc"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pc"/>
</aop:config>
</beans>
注:在链接数据库时引入了一个db.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/bookshopping?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=****
根据自己的需要做适当修改
接下来开始写最重要的controller部分,还是用user作实例,其他的不多加赘述
@Controller
public class UsersController {
@Autowired
private UsersService userService;
@RequestMapping("showReg")
public String showReg(String type,HttpServletRequest request){
if(type != null && type.equals("1")){
request.setAttribute("msg", "两次密码不一致");
}else if(type != null && type.equals("2")){
request.setAttribute("msg", "验证码错误");
}
else if(type != null && type.equals("3")){
request.setAttribute("msg", "注册失败");
}
return "reg";
}
@RequestMapping("reg")
public String reg(Users user,String repassword,String checkcode,HttpServletRequest request){
user.setRole("user");
user.setUpdatetime(DateUtils.format(new Date()));
user.setState(0);//0:表示没有激活,1激活
//将密码与确认密码进行比较
String password = user.getPassword();
if(!password.equals(repassword)){
return "redirect:showReg.action?type=1";
}
//使用md5对密码加密
user.setPassword(Md5Utils.md5(password));
//生成一个激活码
String uuid = UUIDUtils.getUUID();
user.setActivecode(uuid);
//验证验证码是否正确
//从session中获取生成验证码
//String checkcode_session = (String)request.getSession().getAttribute("checkcode_session");
//拿用户输入的验证码与生成的验证码比较
// if(!checkcode.equals(checkcode_session)){
// return "redirect:showReg.action?type=2";
// }
//调用service进行保存
int num = userService.saveUsers(user);
if(num == 0){
return "redirect:showReg.action?type=3";
}
return "redirect:showLogin.action?type=1";
}
@RequestMapping("showLogin")
public String showLogin(String type,Model model){
if("1".equals(type)){
model.addAttribute("msg", "注册成功,请登录");
}else if("2".equals(type)){
model.addAttribute("msg","用户名或密码错误");
}
return "login";
}
//激活账户的方法
@RequestMapping("activation")
public String activation(String code){
//根据激活码查询用户
Users user = userService.findUserByCode(code);
//将账户的状态改为1
user.setState(1);;
userService.updateUsers(user);
return "login";
}
//异步校验用户名
@RequestMapping("checkName")
@ResponseBody
public String checkName(String username){
System.out.println(username);
//根据用户名查询是否存在该用户名
Users user = userService.findUserByName(username);
//当对象不为null,说明用户名存在
if(user != null){
//返回false表示用户名存在
//{"msg":"false"}
return "{\"msg\":\"false\"}";
}
return "{\"msg\":\"true\"}";
}
//登陆
@RequestMapping("login")
public String login(Users user,String remember,String autologin,HttpServletResponse resp,HttpServletRequest request){
Users users = null;
try {
user.setPassword(Md5Utils.md5(user.getPassword()));
users = userService.login(user);
if(users == null){
return "redirect:showLogin?type=2";
}
//记住用户
//判断用户是否勾选记住用户
if(remember != null && remember.equals("on")){
//将用户名以cookie的形式发送到客户端
Cookie cookie;
cookie = new Cookie("username", URLEncoder.encode(users.getUsername(), "utf-8"));
//cookie默认是会话级别的,会随着浏览器的关闭,cookie消失
//通过setMaxAge设置cookie的存活时间,单位秒
cookie.setMaxAge(60 * 60 * 24 * 7);//存储7天
resp.addCookie(cookie);
Cookie cookie1 = new Cookie("save", "on");
cookie1.setMaxAge(60 * 60 * 24 * 7);//存储7天
resp.addCookie(cookie1);
}else{
//将用户名以cookie的形式发送到客户端
Cookie cookie = new Cookie("username", "");
//cookie默认是会话级别的,会随着浏览器的关闭,cookie消失
//通过setMaxAge设置cookie的存活时间,单位秒
cookie.setMaxAge(0);//存储7天
resp.addCookie(cookie);
Cookie cookie1 = new Cookie("save", "");
cookie.setMaxAge(0);//存储7天
resp.addCookie(cookie1);
}
//自动登录
if(autologin != null && autologin.equals("on")){
Cookie cookie = new Cookie("autoLogin", URLEncoder.encode(users.getUsername(), "utf-8") + "-" + users.getPassword());
cookie.setMaxAge(60 * 60 * 24 * 7);
resp.addCookie(cookie);
}
//将登陆的用户存放到session中
request.getSession().setAttribute("user", users);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//判断登陆用户的角色
//如果是admin,跳转到后台管理主页面
if(users.getRole().equals("admin")){
return "redirect:showAdminIndex";
}
return "redirect:showIndex";
}
//退出登录
@RequestMapping("logout")
public String logout(HttpServletRequest request,HttpServletResponse resp){
HttpSession session = request.getSession();
//删除session中存放的登录对象
//session.removeAttribute("user");
//销毁session
session.invalidate();
//去除自动登陆的功能
//将自动登陆cookie中的信息清空
Cookie cookie = new Cookie("autoLogin", "");
cookie.setMaxAge(0);
resp.addCookie(cookie);
return "redirect:showIndex";
}
}
这里用到许多工具类,网上都能查到,就不写上了。
注意:代码中含有@符号的注解都不能删掉,具体作用可以上网查。