ssm整合
- ssm整合的步骤
- 创建maven项目(有webapp文件夹)
- 在pom.xml文件中导入相关依赖
- 创建相关配置文件和包
- 编写web.xml配置文件
- 编写db.properties配置文件
- 编写applicationContext.xml配置文件
- 编写spring-mvc.xml配置文件
- 在数据库中创建表,model包中编写对应实体类
- utils包中编写密码加密和正则表达式的类
- interceptor包中编写拦截器(UserInterceptor类实现HandlerInterceptor接口)
- dao包中编写实体类的mapper接口,接口中编写抽象方法
- 在resources/mapper文件夹下编写对应mapper接口的xml文件
- service包中编写实体类业务层接口以及接口的实现类
- controller包中编写处理器
- 进行测试
ssm整合的步骤
创建maven项目(有webapp文件夹)
注意:
Template: 选项选择:Web application
在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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xinzhi</groupId>
<artifactId>ssm_build</artifactId>
<version>1.0-SNAPSHOT</version>
<name>ssm_build</name>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.target>11</maven.compiler.target>
<maven.compiler.source>11</maven.compiler.source>
<junit.version>5.9.2</junit.version>
</properties>
<dependencies>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
<!--mysql环境-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.31</version>
</dependency>
<!--spring整合jdbc-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--spring整合mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<!--druid连接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<!--分页插件坐标-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<!--springmvc环境-->
<!--springmvc环境-->
<!--springmvc环境-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<!--jackson相关坐标3个-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.0</version>
</dependency>
<!--servlet环境-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!--其他组件-->
<!--其他组件-->
<!--其他组件-->
<!--junit单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--spring整合junit-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
</plugin>
</plugins>
</build>
</project>
创建相关配置文件和包
编写web.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext.xml</param-value>
</context-param>
<!--启动服务器时,通过监听器加载spring运行环境-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 乱码解析器-->
<filter>
<filter-name>CharacterEncodingFilter</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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 前端控制器-->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
编写db.properties配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssmbuild?useUnicode=true&characterEncoding=utf-8
name=root
password=123456
ssmbuild 为自己对应的数据库名称
编写applicationContext.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!--加载properties文件-->
<context:property-placeholder location="classpath:db.properties"/>
<!--数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${name}"/>
<property name="password" value="${password}"/>
</bean>
<!--开启bean注解扫描-->
<context:component-scan base-package="com.xinzhi">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!--事务管理器-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!--开启注解式事务-->
<tx:annotation-driven transaction-manager="txManager"/>
<!--整合mybatis到spring中-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.xinzhi.model"/>
<property name="mapperLocations" value="classpath:mapper/*.xml"/>
<!--分页插件-->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageInterceptor">
<property name="properties">
<props>
<prop key="helperDialect">mysql</prop>
<prop key="reasonable">true</prop>
</props>
</property>
</bean>
</array>
</property>
</bean>
<!--映射扫描-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.xinzhi.dao"/>
</bean>
</beans>
编写spring-mvc.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.xinzhi.controller"/>
<mvc:annotation-driven >
<!-- 消息转换器 -->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/plain;charset=UTF-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/page/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!-- 多媒体解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<property name="maxUploadSize" value="500000"/>
</bean>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/register"/>
<mvc:exclude-mapping path="/login"/>
<bean class="com.xinzhi.interceptor.UserInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
</beans>
在数据库中创建表,model包中编写对应实体类
User
/**
* 用户实体类
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class User {
/**
* 主键id
*/
private int id;
/**
* 昵称
*/
private String nickname;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 年龄
*/
private int age;
/**
* 手机号
*/
private String phone;
}
Result
public class Result<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 成功标志
*/
private boolean success = true;
/**
* 返回处理消息
*/
private String message = "操作成功!";
/**
* 状态码
*/
private Integer code = 0;
/**
* 返回数据对象 data
*/
private T result;
public static long getSerialVersionUID() {
return serialVersionUID;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean success) {
this.success = success;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public T getResult() {
return result;
}
public void setResult(T result) {
this.result = result;
}
public long getTimestamp() {
return timestamp;
}
public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}
/**
* 时间戳
*/
private long timestamp = System.currentTimeMillis();
public Result() {
}
public Result<T> success(String message) {
this.message = message;
this.code = 200;
this.success = true;
return this;
}
public static Result<Object> ok() {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(200);
r.setMessage("成功");
return r;
}
public static Result<Object> ok(String msg) {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(200);
r.setMessage(msg);
return r;
}
public static Result<Object> ok(String msg,Object obj) {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(200);
r.setMessage(msg);
r.setResult(obj);
return r;
}
public static Result<Object> ok(Object data) {
Result<Object> r = new Result<Object>();
r.setSuccess(true);
r.setCode(200);
r.setMessage("成功");
r.setResult(data);
return r;
}
public static Result<Object> error(String msg) {
return error(500, msg);
}
public static Result<Object> error(int code, String msg) {
Result<Object> r = new Result<Object>();
r.setCode(code);
r.setMessage(msg);
r.setSuccess(false);
return r;
}
public Result<T> error500(String message) {
this.message = message;
this.code = 500;
this.success = false;
return this;
}
/**
* 无权限访问返回结果
*/
public static Result<Object> noauth(String msg) {
return error(555, msg);
}
}
utils包中编写密码加密和正则表达式的类
MD5Utils
public class MD5Utils {
public static String encrypt(String password){
MessageDigest md = null;
String s = null;
try {
md = MessageDigest.getInstance("MD5");
md.update(password.getBytes());
s = new BigInteger(1, md.digest()).toString(16);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return s;
}
public static void main(String[] args) {
String encrypt = MD5Utils.encrypt("abcbefgdddd");
System.out.println(encrypt);
}
}
RegUtils
public class RegUtils {
private RegUtils(){
}
public static boolean check(String target,String regex){
//编译正则表达式
Pattern pattern=Pattern.compile(regex);
//创建匹配器
Matcher matcher=pattern.matcher(target);
//进行匹配
if (matcher.matches()){
return true;
}
return false;
}
public static void main(String[] args) {
User tom=User.builder().id(1).username("tom").build();
User lili = User.builder().id(2).username("lili").build();
String str = JSON.toJSONString(tom);
System.out.println(str);
String s="{\"age\":0,\"id\":1,\"username\":\"tom\"}";
User user = JSON.parseObject(s, User.class);
System.out.println(user);
List<User> list = Arrays.asList(tom, lili);
String jList = JSONArray.toJSONString(list);
System.out.println(jList);
String jList1 = "[{\"age\":0,\"id\":1,\"username\":\"tom\"},{\"age\":0,\"id\":2,\"username\":\"lili\"}]";
List<User> users = JSONArray.parseArray(jList1, User.class);
System.out.println(users);
}
}
interceptor包中编写拦截器(UserInterceptor类实现HandlerInterceptor接口)
public class UserInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getHeader("token");
if (token!=null&&token!=""){
Integer id = tokenMapper.selectByToken(token);
if (id!=null&&id>0){
return true;
}
}
String msg = JSON.toJSONString(Result.error(403, "error"));
response.getWriter().println(msg);
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
dao包中编写实体类的mapper接口,接口中编写抽象方法
public interface UserMapper {
User findUserByUsername(String username);
int insert(User user);
User findUserByUsernameAndPassword(@Param("username") String username,@Param("password") String password);
}
在resources/mapper文件夹下编写对应mapper接口的xml文件
<?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.xinzhi.dao.UserMapper">
<!-- sql片段-->
<sql id="user_ref">
id,nickname,username,password,age,phone
</sql>
<insert id="insert">
insert into user(nickname,username,password,age,phone) values (#{nickname},#{username},#{password},#{age},#{phone})
</insert>
<select id="findUserByUsername" resultType="com.xinzhi.model.User">
select <include refid="user_ref"/> from user where username=#{username}
</select>
<select id="findUserByUsernameAndPassword" resultType="com.xinzhi.model.User">
select <include refid="user_ref"/> from user where username=#{username} and password=#{password}
</select>
</mapper>
service包中编写实体类业务层接口以及接口的实现类
接口
public interface IUserService {
Result register(User user);
Result login(User user);
Result logout(String token);
}
实现类
@Service
@Transactional
public class UserServiceImpl implements IUserService {
@Autowired
private UserMapper userMapper;
@Autowired
private TokenMapper tokenMapper;
/**
* 注册
* @param user
* @return
*/
@Override
public Result register(User user) {
//参数校验
//用户名校验
String username = user.getUsername();
if (username!=null&&username!=""){
boolean uname = RegUtils.check(username, "^(?=[a-zA-Z])(?!.*[\\-_]{2})[a-zA-Z0-9\\-_]{8,12}$");
if (!uname){
return Result.error("用户名格式不正确!");
}
}else {
return Result.error("用户名不能为空!");
}
//是否注册过
User uname = userMapper.findUserByUsername(username);
if (uname!=null){
return Result.error("用户名已存在,请重新输入!");
}
//密码校验
String password = user.getPassword();
if (password!=null&&password!=""){
boolean pwd = RegUtils.check(password, "^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]).{8,}$");
if (!pwd){
return Result.error("密码格式不正确!");
}
}else {
return Result.error("密码不能为空!");
}
//密码加密
user.setPassword(MD5Utils.encrypt(password));
//年龄校验
int age = user.getAge();
if (age>120||age<18){
return Result.error("年龄不符合!");
}
//手机号校验
String phone = user.getPhone();
if (phone!=null&&phone!=""){
boolean phone1 = RegUtils.check(phone, "^(1[3-9]\\d{9})$");
if (!phone1){
return Result.error("手机号格式不正确!");
}
}else {
return Result.error("手机号不能为空!");
}
//校验完成,插入数据
int insert = userMapper.insert(user);
return insert>0?Result.ok():Result.error("注册失败!");
}
/**
* 登录
* @param user
* @return
*/
@Override
public Result login(User user) {
String username = user.getUsername();
if (username!=null&&username!=""){
boolean uname = RegUtils.check(username, "^(?=[a-zA-Z])(?!.*[\\-_]{2})[a-zA-Z0-9\\-_]{8,12}$");
if (!uname){
return Result.error("用户名格式不正确!");
}
}else {
return Result.error("用户名不能为空!");
}
String password = user.getPassword();
if (password!=null&&password!=""){
boolean pwd = RegUtils.check(password, "^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[!@#$%^&*()_+\\-=\\[\\]{};':\"\\\\|,.<>\\/?]).{8,}$");
if (!pwd){
return Result.error("密码格式不正确!");
}
}else {
return Result.error("密码不能为空!");
}
password=MD5Utils.encrypt(password);
User user1 = userMapper.findUserByUsernameAndPassword(username, password);
if (user1!=null){
String uuid = UUID.randomUUID().toString();
String token = uuid.replace("-", "");
tokenMapper.insert(token,user1.getId());
return Result.ok("登录成功!",token);
}
return Result.error("登录失败!");
}
/**
* 登出
* @param token
* @return
*/
@Override
public Result logout(String token) {
if (token!=null&&token!=""){
tokenMapper.deleteByToken(token);
}
return Result.ok();
}
}
controller包中编写处理器
@Controller
public class UserController {
@Autowired
private IUserService userService;
@RequestMapping(value = "/register",method = RequestMethod.POST)
@ResponseBody
public Result register(@RequestBody User user){
return userService.register(user);
}
@RequestMapping(value = "/login",method =RequestMethod.POST)
@ResponseBody
public Result login(@RequestBody User user){
return userService.login(user);
}
@RequestMapping(value = "/logout")
@ResponseBody
public Result logout(@RequestHeader("token") String token){
return userService.logout(token);
}
@RequestMapping(value = "/show")
@ResponseBody
public Result show(){
return Result.ok("成功!","首页");
}
}