米米商城
1.开发环境
- 1.服务端
Spring+SpringMVC+Mybatis - 2.数据库
MySQL8.0 - 3.项目管理
Maven - 4.前端
jQuery+BootStrap+JavaScript - 5.开发工具
Idea
2.项目功能
3.项目搭建步骤
1)新建Maven工程
2)修改目录,修改pom.xml文件
3)添加SSM框架的所有依赖
4)拷贝jdbc.porperties到resources目录下
5)新建applicationContext_dao.xml文件,进行数据访问层的配置
6)新建applicationContext_service.xml文件,进行业务逻辑层的配置
7)新建springmvc.xml文件,配置springmvc的框架
8)新建SqlMapConfig.xml文件,进行分页插件的配置
9)对web.xml文件进行配置
10)使用逆向工程生成pojo和mapper的文件
11)开发业务逻辑层,实现登录判断
12)开发控制器AdminAction,完成登录处理
13)改造页面,发送登录请求,验证登录
4.配置文件
4.1 pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bjpowernode</groupId>
<artifactId>mimissm</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<!-- 集中定义依赖版本号 -->
<properties>
<junit.version>4.12</junit.version>
<spring.version>5.2.5.RELEASE</spring.version>
<mybatis.version>3.5.1</mybatis.version>
<mybatis.spring.version>1.3.1</mybatis.spring.version>
<mybatis.paginator.version>1.2.15</mybatis.paginator.version>
<mysql.version>8.0.22</mysql.version>
<slf4j.version>1.6.4</slf4j.version>
<druid.version>1.1.12</druid.version>
<pagehelper.version>5.1.1</pagehelper.version>
<jstl.version>1.2</jstl.version>
<servlet-api.version>2.5</servlet-api.version>
<jsp-api.version>2.0</jsp-api.version>
<jackson.version>2.9.6</jackson.version>
</properties>
<dependencies>
<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jms</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
</dependency>
<dependency>
<groupId>com.github.miemiedev</groupId>
<artifactId>mybatis-paginator</artifactId>
<version>${mybatis.paginator.version}</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>${pagehelper.version}</version>
</dependency>
<!-- MySql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- 连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<!-- junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<!-- JSP相关 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<scope>provided</scope>
<version>${jsp-api.version}</version>
</dependency>
<!-- Jackson Json处理工具包 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20140107</version>
</dependency>
<!--文件异步上传使用的依赖-->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
</dependencies>
<!-- 插件配置 -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
<!--识别所有的配置文件-->
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
4.2 jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/xiaomissm?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
jdbc.username=数据库用户名
jdbc.password=数据库密码
4.3 Mybaties配置文件:SqlMapConfig.xml
Spring中整合了Mybaties中的大部分功能,因此mybaties配置文件中只配置了分页插件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--分页插件的配置-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
</configuration>
4.4 Spring配置文件
整合了Mybaties,将Spring配置文件进了分层配置
4.4.1 applicationContext_dao.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 读取jdbc.properties属性文件-->
<context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
<!-- 创建数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!-- 创建SqlSessionFactoryBean-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 配置数据源-->
<property name="dataSource" ref="dataSource"></property>
<!-- 配置Mybatis的核心配置文件-->
<property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
<!-- 配置实体类-->
<property name="typeAliasesPackage" value="com.bjpowernode.pojo"></property>
</bean>
<!-- 创建mapper文件的扫描器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.bjpowernode.mapper"></property>
</bean>
</beans>
4.4.2 applicationContext_service.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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 设定业务逻辑层的包扫描器,目的时在指定的路径下,使用@service注解的类,Spring负责创建对象,并添加依赖-->
<context:component-scan base-package="com.bjpowernode.service"></context:component-scan>
<!-- 设置事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 添加事务的切面-->
<tx:advice id="myadvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="*select*" read-only="true"/>
<tx:method name="*find*" read-only="true"/>
<tx:method name="*get*" read-only="true"/>
<tx:method name="*search*" read-only="true"/>
<tx:method name="*insert*" propagation="REQUIRED"/>
<tx:method name="*save*" propagation="REQUIRED"/>
<tx:method name="*add*" propagation="REQUIRED"/>
<tx:method name="*delete*" propagation="REQUIRED"/>
<tx:method name="*remove*" propagation="REQUIRED"/>
<tx:method name="*clear*" propagation="REQUIRED"/>
<tx:method name="*update*" propagation="REQUIRED"/>
<tx:method name="*modify*" propagation="REQUIRED"/>
<tx:method name="*change*" propagation="REQUIRED"/>
<tx:method name="*set*" propagation="REQUIRED"/>
<tx:method name="*" propagation="SUPPORTS"/>
</tx:attributes>
</tx:advice>
<!-- 完成切面和切入点的织入-->
<aop:config>
<aop:pointcut id="mypointcut" expression="execution(* com.bjpowernode.service.*.*(..))"/>
<aop:advisor advice-ref="myadvice" pointcut-ref="mypointcut"></aop:advisor>
</aop:config>
</beans>
4.5 SpringMVC配置文件:springmvc.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:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 设置包扫描器-->
<context:component-scan base-package="com.bjpowernode.controller"></context:component-scan>
<!-- 设置视图解析器 /admin/ main .jsp -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/admin/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 设置文件上传核心组件-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
</bean>
<!-- 设置注解驱动-->
<mvc:annotation-driven></mvc:annotation-driven>
</beans>
4.6 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 添加字符编码过滤器-->
<filter>
<filter-name>encode</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>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encode</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 注册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:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
<!-- 注册Spring框架-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext_*.xml</param-value>
</context-param>
</web-app>
5.逆向工程
用来快速生成pojo和mapper文件
1.配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/mimissm?useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true" userId="root" password="root">
<!--识别主键-->
<property name="nullCatalogMeansCurrent" value="true"/>
</jdbcConnection>
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.bjpowernode.pojo"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.bjpowernode.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.bjpowernode.mapper"
targetProject=".\src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table schema="" tableName="admin"></table>
<table schema="" tableName="product_info"></table>
<table schema="" tableName="product_type"></table>
</context>
</generatorConfiguration>
2.运行代码
package com.oracle.mybatis.tools;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
public class GeneratorSqlmap {
public void generator() throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//指定 逆向工程配置文件
File configFile = new File("generatorConfig.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,
callback, warnings);
myBatisGenerator.generate(null);
}
public static void main(String[] args) throws Exception {
try {
GeneratorSqlmap generatorSqlmap = new GeneratorSqlmap();
generatorSqlmap.generator();
} catch (Exception e) {
e.printStackTrace();
}
}
}
6.登录功能
6.1 MD5加密
package com.bjpowernode.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Util {
/**
* 1.MD5(message-digest algorithm 5)信息摘要算法,
* 它的长度一般是32位的16进制数字符串(如81dc9bdb52d04dc20036dbd8313ed055)
* 2.由于系统密码明文存储容易被黑客盗取
* 3.应用:注册时,将密码进行md5加密,存到数据库中,防止可以看到数据库数据的人恶意篡改。
* 登录时,将密码进行md5加密,与存储在数据库中加密过的密码进行比对
* 4.md5不可逆,即没有对应的算法,从产生的md5值逆向得到原始数据。
* 但是可以使用暴力破解,这里的破解并非把摘要还原成原始数据,如暴力枚举法。
*
*/
public final static String getMD5(String str){
try {
MessageDigest md = MessageDigest.getInstance("SHA");//创建具有指定算法名称的摘要
md.update(str.getBytes()); //使用指定的字节数组更新摘要
byte mdBytes[] = md.digest(); //进行哈希计算并返回一个字节数组
String hash = "";
for(int i= 0;i<mdBytes.length;i++){ //循环字节数组
int temp;
if(mdBytes[i]<0) //如果有小于0的字节,则转换为正数
temp =256+mdBytes[i];
else
temp=mdBytes[i];
if(temp<16)
hash+= "0";
hash+=Integer.toString(temp,16); //将字节转换为16进制后,转换为字符串
}
return hash;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
}
6.2 业务层代码
package com.bjpowernode.service.impl;
import com.bjpowernode.mapper.AdminMapper;
import com.bjpowernode.pojo.Admin;
import com.bjpowernode.pojo.AdminExample;
import com.bjpowernode.service.AdminService;
import com.bjpowernode.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @author zwghdu
* @create 2021-08-29-16:55
*/
@Service
public class AdminServiceImpl implements AdminService {
//在业务逻辑层中,一定给会有数据访问层的对象
@Autowired
AdminMapper adminMapper;
@Override
public Admin login(String name, String pwd) {
//根据传入的用户名到db中查询相应的用户对象
//如果有条件,则一定要创建AdminExample的对象,用来封装条件
AdminExample example = new AdminExample();
/**
* 如何添加条件
* select * from admin where a_name='admin'
*/
//添加用户名a_name条件
example.createCriteria().andANameEqualTo(name);
List<Admin> list = adminMapper.selectByExample(example);
//判断是否查到
if(list.size()>0){
Admin admin = list.get(0);
//如果查询到用户对象,再进行密码的比对,注意密码是密文
/**
* 分析:
* admin.getApass==>c984aed014aec7623a54f0591da07a85fd4b762d
* pwd==>000000
* 在进行密码对比时,要将传入的pwd进行MD5加密,再与数据库中查到的对象的密码进行对比
*/
String miPwd = MD5Util.getMD5(pwd);
if(miPwd.equals(admin.getaPass())){
return admin;
}
}
return null;
}
}
6.3 控制层代码
package com.bjpowernode.controller;
import com.bjpowernode.pojo.Admin;
import com.bjpowernode.service.AdminService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import javax.servlet.http.HttpServletRequest;
/**
* @author zwghdu
* @create 2021-08-29-17:17
*/
@Controller
@RequestMapping("/admin")
public class AdminAction {
//切记:在所有的界面层,一定会有业务逻辑层的对象
@Autowired
AdminService adminService;
//实现登录判断,并进行相应的跳转
@RequestMapping("/login")
public String login(String name, String pwd, HttpServletRequest request){
Admin admin = adminService.login(name,pwd);
if (admin != null){
//登录成功
request.setAttribute("admin",admin);
return "main";
}else {
//登录失败
request.setAttribute("errmsg","用户名或密码不正确!");
return "login";
}
}
}