使用SSM框架搭建Web服务器实现登录功能(Spring+SpringMVC+Mybatis)

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 使用SSM框架搭建Web服务器实现登录功能(Spring+SpringMVC+Mybatis)http://www.bieryun.com/1576.html SSM框架搭建流程,经过分析本项目源码,流程应该是这样的: database–>Entity.

使用SSM框架搭建Web服务器实现登录功能(Spring+SpringMVC+Mybatis)

SSM框架搭建流程,经过分析本项目源码,流程应该是这样的:

database–>Entity.java–>mapper.xml–>Mapper.java–>Dao.java–>DaoImpl.java–>Service.java–>ServiceImpl.java–>Controller.java–>login.jsp

  • 根据需要建立数据库、数据表、字段;
  • 根据表中字段建立实体类;
  • 在Mapper中实现对数据库的增删改查操作;
  • 设计DAO(data access object)数据操作对象接口;
  • 设计Service,通过DAO获取对象,然后进行业务逻辑实现;
  • 设计控制层Controller,用于从页面获取请求,调用Service处理并将处理结果返回给页面。

根据上面所列,下面就按照这个流程进行设计。


数据库设计

使用MySQL数据库:

  • 建立数据库 DB_TEST
CREATE DATABASE DB_TEST;
  • 建立用户表 T_USER
CREATE TABLE T_USER (
    ID INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
    USERNAME VARCHAR(16) NOT NULL,
    PASSWORD VARCHAR(16) NOT NULL
    );
  • 插入一条用户信息
INSERT INTO T_USER (USERNAME,PASSWORD) VALUES ("admin","123");

建立USER实体类

public class User {

   private int id;
   private String username;
   private String password;

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = 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;
    }
}

Mapper实现增删改查


  • UserMapper接口,定义通过用户名获取用户对象的方法
public interface UserMapper {

    public User getUserByName(String username);
}

  • usermapper.xml,用于操作数据库,实现接口中的方法
  <mapper namespace="com.crm.mapper.UserMapper">

    <resultMap type="com.crm.entity.User" id="userMap">
        <id property="id" column="id" />
        <result property="username" column="username" />
        <result property="password" column="password" />        
    </resultMap>

    <!-- 此处select标签的id值对应Mapper类中方法名 -->
    <select id="getUserByName" parameterType="string" resultMap="userMap">
            <!-- 此处写sql语句,#{Mapper类传入的参数} -->
            select * from T_USER where username = #{username}
    </select>
</mapper>

DAO 数据操作对象


  • DAO接口 UserDao.java
public interface UserDao {
    //接口方法,通过用户名得到User对象
    public User findUserByName(String username);
}

  • DAO接口实现 UserDaoImpl.java

@Repository对应数据访问层Bean

@Repository(value=”userDao”)注解是告诉Spring,让Spring创建一个名字叫“userDao”的UserDaoImpl实例。

当Service需要使用Spring创建的名为“userDao”的UserDaoImpl实例时,
就可以使用@Resource(name =”userDao”)注解告诉Spring,Spring把创建好的userDao注入给Service即可。

@Repository("userDao")
public class UserDaoImpl implements UserDao {
    //注解引用Mapper类资源
    @Resource(name = "userMapper")
    private UserMapper userMapper;

    /* 根据用户名查找用户对象 */
    public User findUserByName(String username) {
        //调用Mapper类从数据库中得到User对象
        return userMapper.getUserByName(username);
    }
}

业务层 Service


  • 业务层接口 UserService.java
public interface UserService {
    // 通过用户名及密码核查用户登录
    public User checkLogin(String username, String password);
}

  • 业务层接口实现类 UserServiceImpl.java

@Service对应的是业务层Bean

这样当Action需要使用UserServiceImpl的的实例时,就可以由Spring创建好的”userService”注入给Action:在Action只需要声明一个名字叫“userService”的变量来接收由Spring注入的”userService”即可

@Service("userService")
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao userDao;

    /* 登陆验证 */
    public User checkLogin(String username, String password) {
        //根据用户名实例化用户对象
        User user = userDao.findUserByName(username);
        if (user != null && user.getPassword().equals(password)) {
            return user;
        }
        return null;
    }
}

控制层 Controller


@Controller对应表现层的Bean,也就是Action

注意:如果@Controller不指定其value【@Controller】,则默认的bean名字为这个类的类名首字母小写,如果指定value【@Controller(value=”UserAction”)】或者【@Controller(“UserAction”)】,则使用value作为bean的名字。


@Scope(“prototype”)表示将Action的范围声明为原型

可以利用容器的scope=”prototype”来保证每一个请求有一个单独的Action来处理,避免struts中Action的线程安全问题。

spring 默认scope 是单例模式(scope=”singleton”),这样只会创建一个Action对象,每次访问都是同一Action对象,数据不安全。

struts2 是要求每次次访问都对应不同的Action,scope=”prototype” 可以保证当有请求的时候都创建一个Action对象


@RequestMapping(“/user”)

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。


本项目中,该Controller类RequestMapping(”user”)
该Controller类的login方法RequestMapping(”login”)
所以登录页面中用户登录的 action=”/ssm/user/login”


@Controller
@Scope(value="prototype")
@RequestMapping("/user")
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping(value="/login",method=RequestMethod.POST)
    public String login(User user,Model model) throws Exception {
        user=userService.checkLogin(user.getUsername(), user.getPassword());
        if(user!=null){
            model.addAttribute(user);
            return "welcome";// 路径 WEB-INF/pages/welcome.jsp            
        }
        return "fail";
    }
}

页面 JSP


<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>用户登录</title>
</head>

<body>
    <form action="/ssm/user/login" method="post" id="myform">
        <input type="text" id="username" name="username"/>
        <input type="password" id="password" name="password"/>
        <input type="submit" value="提交" id="login" />
    </form>
</body>

</html>

DEMO工程中的所有配置文件


applicationContext.xml

这个文件是Spring公共配置文件,下面分块进行解析。

  • 数据库配置文件database.properties的引入
    <bean id="property"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
            <!-- classpath 即src根目录 -->              
            <value>classpath:database.properties</value>
            </list>
        </property>
    </bean>

  • 数据库连接池的配置

数据库连接池可以让服务器预先与数据库建立部分连接,存入内存中,以减少连接数据库的耗时操作。
此处定义使用C3P0连接池的数据源。

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close">

        <!-- 指定连接数据库的JDBC驱动 -->
        <property name="driverClass">
            <value>${mysql.driver_class}</value>
        </property>

        <!-- 连接数据库所用的URL -->
        <property name="jdbcUrl">
            <value>${mysql.connection.url}</value>
        </property>

        <!-- 连接数据库的用户名 -->
        <property name="user">
            <value>${mysql.connection.username}</value>
        </property>

        <!-- 连接数据库的密码 -->
        <property name="password">
            <value>${mysql.connection.password}</value>
        </property>

        <!-- 设置数据库连接池的最大连接数 -->
        <property name="maxPoolSize">
            <value>30</value>
        </property>

        <!-- 设置数据库连接池的最小连接数 -->
        <property name="minPoolSize">
            <value>2</value>
        </property>

        <!-- 设置数据库连接池的初始化连接数 -->
        <property name="initialPoolSize">
            <value>2</value>
        </property>

        <!-- 设置数据库连接池的连接的最大空闲时间,单位为秒 -->
        <property name="maxIdleTime">
            <value>10</value>
        </property>
    </bean>

  • 自动扫描配置

使用< context:component-scan>标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean

    <context:component-scan base-package="com.crm.*">
        <!-- 不扫描注解为controller的类型 -->
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

  • 集成Mybatis

SqlSessionFactoryBean是一个工厂bean,它的作用就是解析配置(数据源、别名等)。

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <!-- 引用上面已经配置好的数据库连接池 -->
        <property name="dataSource" ref="dataSource" />

        <!-- Mybatis的配置文件路径 -->
        <property name="configLocation" value="classpath:mybatis.xml" />

        <!-- mapper配置路径 -->
        <property name="mapperLocations">
            <list>
                <value>classpath:com/crm/mapper/*.xml</value>
            </list>
        </property>
    </bean>

  • Mapper扫描配置

dao需要配置,如果数量大不适合一个个配置,需要使用mapper自动扫描来批量进行配置。

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.crm.mapper" />
    </bean>

  • Mybatis事务管理配置
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

数据库配置文件database.properties

mysql.driver_class=com.mysql.jdbc.Driver
<!-- DB_TEST为新建的数据库名 -->
mysql.connection.url=jdbc:mysql://localhost:3306/DB_TEST
<!-- 登录数据库的用户名密码 -->
mysql.connection.username=root
mysql.connection.password=root

日志管理文件 log4j.properties

此处省略,入门阶段暂不考虑这么高端的日志用法。


Mybatis配置文件

通过使用别名,可以缩短类名的长度,但是只能在配置文件中使用。

<configuration>
    <!-- 别名 -->
    <typeAliases>
        <typeAlias type="com.crm.entity.User" alias="user" />
    </typeAliases>
</configuration>

web配置文件

此配置文件注释比较清楚,就不单独解析了。

    <display-name>crm</display-name>

    <!--一个server下如果有多个项目,要对webAppRootKey进行配置,让log能将日志写到对应项目根目录下-->
    <context-param>
           <param-name>webAppRootKey</param-name>
           <param-value>crm.root</param-value>
    </context-param> 

    <!-- 由Sprng载入的Log4j配置文件位置 -->
    <context-param>
           <param-name>log4jConfigLocation</param-name>
           <param-value>classpath:log4j.properties</param-value>
    </context-param>

    <!-- Spring默认刷新Log4j配置文件的间隔,单位为millisecond -->
    <context-param>
           <param-name>log4jRefreshInterval</param-name>
           <param-value>60000</param-value>
    </context-param>

    <!-- Web 项目 Spring 加载 Log4j 的监听  -->
    <listener> 
        <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> 
    </listener> 

    <!-- 设置Spring容器加载配置文件路径 -->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:springContext/*Context.xml</param-value>
    </context-param>

    <!-- 加载Spring容器配置 -->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- 防止内存泄漏的监听器 -->
      <listener>
        <listener-class>
            org.springframework.web.util.IntrospectorCleanupListener
        </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>/WEB-INF/springmvc.xml</param-value>
        </init-param>
        <!-- 立马启动servlet -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- servlet-mapping配置 -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!-- 解决工程编码过滤器 -->
    <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>

    <!-- 设置默认打开页面列表 -->
    <welcome-file-list>
        <welcome-file>login.jsp</welcome-file>
    </welcome-file-list>
</web-app>

springmvc配置文件

之前扫描专门忽略了Controller,在此处扫描。

例如在Controller类中常有类似return welcome这样的语句

其实完整的应该是return WEB-INF/pages/welcome.jsp

    <!-- 注解Controller扫描器 -->
    <context:component-scan base-package="com.crm.controller"/>

    <!-- 静态资源访问 -->
     <mvc:resources location="/img/" mapping="/img/**"/>  
     <mvc:resources location="/js/" mapping="/js/**"/> 
     <mvc:resources location="/common/" mapping="/common/**"/>   

    <!-- 注解功能的默认配置,处理器和映射器 -->
    <bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

    <bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

    <!-- 前后缀配置 -->
    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
3月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
3月前
|
开发框架 前端开发 Go
【GoGin】(0)基于Go的WEB开发框架,GO Gin是什么?怎么启动?本文给你答案
Gin:Go语言编写的Web框架,以更好的性能实现类似Martini框架的APInet/http、Beego:开源的高性能Go语言Web框架、Iris:最快的Go语言Web框架,完备的MVC支持。
411 1
|
6月前
|
Java Linux 网络安全
Linux云端服务器上部署Spring Boot应用的教程。
此流程涉及Linux命令行操作、系统服务管理及网络安全知识,需要管理员权限以进行配置和服务管理。务必在一个测试环境中验证所有步骤,确保一切配置正确无误后,再将应用部署到生产环境中。也可以使用如Ansible、Chef等配置管理工具来自动化部署过程,提升效率和可靠性。
639 13
|
7月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:路由、中间件、参数校验
Gin框架以其极简风格、强大路由管理、灵活中间件机制及参数绑定校验系统著称。本文详解其核心功能:1) 路由管理,支持分组与路径参数;2) 中间件机制,实现全局与局部控制;3) 参数绑定,涵盖多种来源;4) 结构体绑定与字段校验,确保数据合法性;5) 自定义校验器扩展功能;6) 统一错误处理提升用户体验。Gin以清晰模块化、流程可控及自动化校验等优势,成为开发者的优选工具。
|
6月前
|
前端开发 Java API
Spring Cloud Gateway Server Web MVC报错“Unsupported transfer encoding: chunked”解决
本文解析了Spring Cloud Gateway中出现“Unsupported transfer encoding: chunked”错误的原因,指出该问题源于Feign依赖的HTTP客户端与服务端的`chunked`传输编码不兼容,并提供了具体的解决方案。通过规范Feign客户端接口的返回类型,可有效避免该异常,提升系统兼容性与稳定性。
425 0
|
7月前
|
开发框架 安全 前端开发
Go Web开发框架实践:模板渲染与静态资源服务
Gin 是一个功能强大的 Go Web 框架,不仅适用于构建 API 服务,还支持 HTML 模板渲染和静态资源托管。它可以帮助开发者快速搭建中小型网站,并提供灵活的模板语法、自定义函数、静态文件映射等功能,同时兼容 Go 的 html/template 引擎,具备高效且安全的页面渲染能力。
|
7月前
|
开发框架 JSON 中间件
Go语言Web开发框架实践:使用 Gin 快速构建 Web 服务
Gin 是一个高效、轻量级的 Go 语言 Web 框架,支持中间件机制,非常适合开发 RESTful API。本文从安装到进阶技巧全面解析 Gin 的使用:快速入门示例(Hello Gin)、定义 RESTful 用户服务(增删改查接口实现),以及推荐实践如参数校验、中间件和路由分组等。通过对比标准库 `net/http`,Gin 提供更简洁灵活的开发体验。此外,还推荐了 GORM、Viper、Zap 等配合使用的工具库,助力高效开发。
|
6月前
|
SQL Java 数据库连接
Spring、SpringMVC 与 MyBatis 核心知识点解析
我梳理的这些内容,涵盖了 Spring、SpringMVC 和 MyBatis 的核心知识点。 在 Spring 中,我了解到 IOC 是控制反转,把对象控制权交容器;DI 是依赖注入,有三种实现方式。Bean 有五种作用域,单例 bean 的线程安全问题及自动装配方式也清晰了。事务基于数据库和 AOP,有失效场景和七种传播行为。AOP 是面向切面编程,动态代理有 JDK 和 CGLIB 两种。 SpringMVC 的 11 步执行流程我烂熟于心,还有那些常用注解的用法。 MyBatis 里,#{} 和 ${} 的区别很关键,获取主键、处理字段与属性名不匹配的方法也掌握了。多表查询、动态
189 0
|
6月前
|
JSON 前端开发 Java
第05课:Spring Boot中的MVC支持
第05课:Spring Boot中的MVC支持
297 0
|
3月前
|
弹性计算 运维 安全
阿里云轻量应用服务器与云服务器ECS啥区别?新手帮助教程
阿里云轻量应用服务器适合个人开发者搭建博客、测试环境等低流量场景,操作简单、成本低;ECS适用于企业级高负载业务,功能强大、灵活可扩展。二者在性能、网络、镜像及运维管理上差异显著,用户应根据实际需求选择。
311 10