idea搭建ssh项目(spring+struts2+hibernate)

插件版本

Spring-5.2.3.RELEASE
struts2-core:2.5.30
Hibernate 5.4.11

创建项目

选择spring版本,选择下载依赖包
在这里插入图片描述
选择struts2 直接选择下载依赖包(会失败),可以先选择稍后处理;
在这里插入图片描述
选择hibernate版本,选择下载依赖包
在这里插入图片描述
点击 next
填写项目名称,点击finish
在这里插入图片描述

一. 引入依赖包

Spring-5.2.3.RELEASE --已下载
Hibernate 5.4.11 --已下载

struts2-spring-plugin-2.5.30.jar --struts2整合Spring所需jar
spring-web-5.2.3.RELEASE.jar

aspectjweaver-1.9.8.jar --处理事务和AOP所需的包

mysql-connector-java-8.0.22.jar --数据库依赖包
commons-dbcp-1.4.jar --连接池
commons-pool-1.5.4.jar

如下方式,可以下载添加依赖包
在这里插入图片描述
struts2-spring-plugin-2.5.30中依赖的Spring-4.3.26.RELEASE 移除,
下载spring-web-5.2.3.RELEASE.jar
在这里插入图片描述

至此依赖下载完成
在这里插入图片描述

二. 新增配置文件applicationContext.xml

右击 WEB-INF,新增配置文件 applicationContext.xml
在这里插入图片描述
编写applicationContext.xml 配置sessionFactory

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://localhost:33068/sshdemo?characterEncoding=utf8&amp;connectTimeout=1000&amp;socketTimeout=3000&amp;autoReconnect=true&amp;useUnicode=true&amp;useSSL=false&amp;serverTimezone=UTC"></property>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <!-- session factory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
    </bean>

做如下添加
在这里插入图片描述
在这里插入图片描述

三. 修改配置文件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">

    <!--配置环境参数,指定Spring配置文件的位置-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
        </param-value>
    </context-param>

    <!--配置监听器,初始化Spring容器-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <display-name>demo</display-name>
    <welcome-file-list>
        <welcome-file>/index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

四. 新增package

在这里插入图片描述

五. 连接数据库,生成实体类

数据库sql

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `userName` varchar(20) NOT NULL,
  `trueName` varchar(20) NOT NULL,
  `password` varchar(20) NOT NULL,
  `role` varchar(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=13 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of usertable
-- ----------------------------
INSERT INTO `usertable` VALUES ('1', 'admin', 'admin', 'admin', '管理员');
INSERT INTO `usertable` VALUES ('2', '剑谪仙', '剑谪仙', 'admin', '学生');
INSERT INTO `usertable` VALUES ('3', '王五', '王五', 'admin', '学生');
INSERT INTO `usertable` VALUES ('6', '秦假仙', '秦假仙', 'qjx', '教师');
INSERT INTO `usertable` VALUES ('7', '素还真', '素还真', 'shz', '教师');
INSERT INTO `usertable` VALUES ('8', '风月主人', '风月主人', 'admin', '学生');

在这里插入图片描述
在这里插入图片描述
连接成功,出现下图;
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
ok后, com.test.ssh.entity包下生成 UserEntity 类
applicationContext.xml也修改了,

<!-- session factory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
                <prop key="hibernate.connection.url">
                    <![CDATA[jdbc:mysql://localhost:33068/sshdemo?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false]]></prop>
                <prop key="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</prop>
            </props>
        </property>
        <property name="annotatedClasses">
            <list>
                <value>com.test.ssh.entity.UserEntity</value>
            </list>
        </property>
    </bean>

六. 编写dao,sevice,action,jsp 代码

在这里插入图片描述

BaseDao代码

package com.test.ssh.dao;

import org.springframework.orm.hibernate5.support.HibernateDaoSupport;

import java.util.List;

public class BaseDao<T> extends HibernateDaoSupport {

    // 新增数据
    public void save(T entity) {
        try
        {
            getHibernateTemplate().save(entity);
        }
        catch (Throwable e)
        {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }

    // 删除数据
    public void delete(T entity) {
        try
        {
            getHibernateTemplate().delete(entity);
        }
        catch (Throwable e)
        {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }

    // 修改数据
    public void update(T entity) {
        try
        {
            getHibernateTemplate().update(entity);
        }
        catch (Throwable e)
        {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }

    // 查找数据
    public List<T> find(String hql) {
        try
        {
            List list = (List<T>) getHibernateTemplate().find(hql);
            return list;
        }
        catch (Throwable e)
        {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }

    // 查找数据
    public List<T> find(String hql, Object... params) {
        try
        {
            List list = (List<T>) getHibernateTemplate().find(hql, params);
            return list;
        }
        catch (Throwable e)
        {
            logger.error(e.getMessage(), e);
            throw e;
        }
    }
}

UserDao 代码

package com.test.ssh.dao;


import com.test.ssh.entity.UserEntity;

import java.util.List;

public class UserDao extends BaseDao<UserEntity>  {

    // 根据账号密码,查找用户
    public UserEntity queryByUserName(String name, String pswd) {
        String hql = "FROM com.test.ssh.entity.UserEntity u WHERE userName=?0 AND password=?1 ";
        List<UserEntity> list = find(hql, name, pswd);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    // 获取所有用户
    public List<UserEntity> getAll() {
        String hql = "FROM com.test.ssh.entity.UserEntity ";
        return find(hql);
    }

    // 根据id查询用户
    public UserEntity queryById(int id) {
        String hql = "FROM com.test.ssh.entity.UserEntity u WHERE id=?0";
        List<UserEntity> list = find(hql, id);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }
}

UserService 代码

package com.test.ssh.service;

import com.test.ssh.dao.UserDao;
import com.test.ssh.entity.UserEntity;
import org.springframework.transaction.annotation.Transactional;


import java.util.List;

@Transactional
public class UserService {
    UserDao userDao;

    // 根据账号密码,查找用户
    public UserEntity queryByUserName(String name, String pswd) {
        return userDao.queryByUserName(name, pswd);
    }

    // 新增用户
    public int save(UserEntity user) {
        userDao.save(user);
        return user.getId();
    }

    // 删除用户
    public void delete(UserEntity user) {
        userDao.delete(user);
    }

    // 修改用户
    public void update(UserEntity user) {
        userDao.update(user);
    }

    // 获取所有用户
    public List<UserEntity> getAll() {
        return userDao.getAll();
    }

    // 根据id查询用户
    public UserEntity queryById(int id) {
        return userDao.queryById(id);
    }

    public UserDao getUserDao() {
        return userDao;
    }

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}

UserAction 代码

package com.test.ssh.action;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.test.ssh.entity.UserEntity;
import com.test.ssh.service.UserService;

import java.util.List;

public class UserAction extends ActionSupport {
    UserEntity user;
    UserService userService;

    // 登录
    public String login() {
        String name = user.getUserName();
        String pswd = user.getPassword();

        UserEntity u = userService.queryByUserName(name, pswd);
        if (u == null) {
            addFieldError("errMsg", "用户名或密码不正确!");
            return "error";
        } else {
            return "userlist";
        }
    }

    // 获取 修改或新增界面
    public String modify() {
        int id = user.getId();
        if(id == 0){ // 新增
            user = new UserEntity();
        }else { // 修改
            user = userService.queryById(id);
        }

        ActionContext.getContext().put("user", user);
        return "modify";
    }

    // 保存数据,进行新增或修改  成功后返回列表页面
    public String save() {
        int id = user.getId();
        if(id == 0){ // 新增
            id = userService.save(user);
        }else { // 修改
            userService.update(user);
        }
        return "userlist";
    }

    // 删除数据, 成功后返回列表页面
    public String delete() {
        userService.delete(user);
        return "userlist";
    }

    // 返回用户列表
    public String getUserList() {
        List<UserEntity> list = userService.getAll();
        ActionContext.getContext().put("list", list);
        return "userlist";
    }

    public UserEntity getUser() {
        return user;
    }

    public void setUser(UserEntity user) {
        this.user = user;
    }

    public UserService getUserService() {
        return userService;
    }

    public void setUserService(UserService userService) {
        this.userService = userService;
    }
}

index.jsp 代码

<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>

<%
  String path = request.getContextPath();
  String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <base href="<%= basePath %>">
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  <title>登录</title>
</head>
<body>
<div>
  <s:form action="login" method="post" theme="simple">
    <div class="login">
      <div class="login_title">
        用户登录
      </div>

      <fieldset>
        <legend>账户信息</legend>
        <p>
          请输入用户账户信息进行登录,若没有账户,请先<a href="${pageContext.request.contextPath}/modify?user.id=0">注册</a>
        </p>
        <table>
          <tr>
            <td>用户名</td>
            <td>
              <s:textfield name="user.userName"></s:textfield><s:fielderror fieldName="user.userName"/>
            </td>
          </tr>

          <tr>
            <td>密码</td>
            <td>
              <s:password name="user.password"></s:password><s:fielderror fieldName="user.password"/>
            </td>
          </tr>
        </table>
      </fieldset>

      <s:submit value="提    交" cssClass="login_submit"></s:submit>
      <s:reset value="重置" cssClass="login_submit"></s:reset>
    </div>
  </s:form>
  <s:if test="hasFieldErrors()">
    <s:property  value="fieldErrors['errMsg'][0]"/>
  </s:if>
</div>
</body>
</html>

userlist.jsp 代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags"%>

<html>
<head>
    <title>成功</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        .infotable {
            margin: 0px auto;
            border: 2px solid skyblue;
            width: 80%;
        }

        tr,
        td {
            border: 1px solid black;
        }
        td {
            text-align: center;
        }

        tr:first-child {
            font-weight: 700;
        }
    </style>

    <script src='http://apps.bdimg.com/libs/jquery/1.9.1/jquery.min.js'></script>
    <script type="text/javascript">
        $(function(){
            //删除用户
            $(".delete").click(function(){
                var str=this.lang.split("!");
                if(!confirm("你确定要删除"+ str[1] +"这个用户吗?"))
                {
                    return;
                }
                //jquery ajax方式请求action
                $.post("${pageContext.request.contextPath}/delete",{"user.id":str[0]},function(){
                    location.href="${pageContext.request.contextPath}/getList";
                    alert("删除成功!")
                });
                <%--$.post("${pageContext.request.contextPath}/delete",{"user.id":str[0]});--%>

            });

            //修改用户
            $(".modify").click(function(){
                //为保证跳转的控制权在action中
                location.href="${pageContext.request.contextPath}/modify?user.id=" + this.lang;
            });
        });
    </script>
</head>
<body>
<h1>用户列表</h1>
<table class="infotable" cellspacing="0px" cellpadding="0px">
    <tr>
        <td>编号</td>
        <td>姓名</td>
        <td>账号</td>
        <td>密码</td>
        <td>角色</td>
        <td>操作</td>
    </tr>
    <s:iterator value="list">
        <tr>
            <td><s:property value="id"/></td>
            <td><s:property value="trueName"/></td>
            <td><s:property value="userName"/></td>
            <td><s:property value="password"/></td>
            <td><s:property value="role"/></td>
            <td>
                <a href="#" class="modify" lang="0">新增</a>
                <a href="#" class="modify" lang="<s:property value="id"/>">修改</a>
                <a href="#" class="delete" lang="<s:property value="id"/>!<s:property value="userName"/>">删除</a>
            </td>
        </tr>
    </s:iterator>
</table>
</body>
</html>

modify.jsp 代码

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>新增/编辑</h1>
<form method="post" action="${pageContext.request.contextPath}/save">
<li>
    <label>编号</label>
    <input type="text" name="user.id" value="<s:property value="#user.id"/>" readonly>
</li>
<li>
    <label>姓名</label>
    <input type="text" name="user.trueName"  value="<s:property value="#user.trueName"/>">
</li>
<li>
    <label>账号</label>
    <input type="text" name="user.userName"  value="<s:property value="#user.userName"/>">
</li>
<li>
    <label>密码</label>
    <input type="text" name="user.password"  value="<s:property value="#user.password"/>">
</li>
<li>
    <label>角色</label>
    <input type="text" name="user.role"  value="<s:property value="#user.role"/>">
</li>
<input type="submit" value="保存">
<a href="${pageContext.request.contextPath}/getList">取消</a>
</form>
</body>
</html>

struts.xml 代码

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC
        "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
        "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
    <constant name="struts.enable.DynamicMethodInvocation" value="false"/>
    <constant name="struts.devMode" value="true"/>
    <!-- struts.objectFactory=spring    struts2框架就会把bean转发给spring来创建,装配,注入。
    但是bean创建完成之后,还是由struts容器来管理其生命周期。
    需要依赖包 struts2-spring-plugin-2.5.30.jar 版本和struts2一致 -->
    <constant name="struts.objectFactory" value="spring" />

    <!-- 用户管理 -->
    <package name="userManage" extends="struts-default">
        <!-- 登录 返回列表-->
        <action name="login" class="com.test.ssh.action.UserAction" method="login">
            <result name="error">/index.jsp</result>
            <result name="userlist" type="redirectAction">getList</result>
        </action>

        <!-- 修改 返回修改界面 -->
        <action name="modify" class="com.test.ssh.action.UserAction" method="modify">
            <result name="modify">/jsp/user/modify.jsp</result>
        </action>

        <!-- 保存 修改和新增 返回列表-->
        <action name="save" class="com.test.ssh.action.UserAction" method="save">
            <result name="userlist" type="redirectAction">getList</result>
        </action>

        <!-- 删除 返回列表 -->
        <action name="delete" class="com.test.ssh.action.UserAction" method="delete">
            <result name="userlist" type="redirectAction">getList</result>
        </action>

        <!-- 返回列表-->
        <action name="getList" class="com.test.ssh.action.UserAction" method="getUserList">
            <result name="userlist">/jsp/user/userlist.jsp</result>
        </action>
    </package>
</struts>

applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
        <property name="url" value="jdbc:mysql://127.0.0.1:33068/sshdemo?characterEncoding=utf8&amp;connectTimeout=1000&amp;socketTimeout=3000&amp;autoReconnect=true&amp;useUnicode=true&amp;useSSL=false&amp;serverTimezone=UTC"></property>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <!-- session factory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
                <prop key="hibernate.show_sql">false</prop>
            </props>
        </property>
        <property name="annotatedClasses">
            <list>
                <value>com.test.ssh.entity.UserEntity</value>
            </list>
        </property>
    </bean>

    <!-- 用户 userDao -->
    <bean id="userDao" class="com.test.ssh.dao.UserDao">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>
    <!-- 用户 userService -->
    <bean id="userService" class="com.test.ssh.service.UserService">
        <property name="userDao" ref="userDao"/>
    </bean>

</beans>

七. 配置tomcat,调试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
调试效果
在这里插入图片描述

八. 问题

org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): 
Turn your Session into FlushMode.COMMIT/AUTO or remove 'readOnly' marker from transaction definition.

Spring + Hibernate 5 对事务要求更严格,所有读写操作必须通过事务提交;
新增配置applicationContext_tx.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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--事务管理器-->
    <bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"></property>
    </bean>

    <aop:config>
        <!-- execution(public * *.*.*..*.*(..)) 为自己项目中操作数据库中的方法 -->
        <aop:pointcut id="pointcut" expression="execution(* com.test.ssh.service.*.*(..))" />
        <aop:advisor pointcut-ref="pointcut" advice-ref="txAdvice" />
    </aop:config>

    <!-- 配置事务增强 -->
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <!-- 配置需要进行事务管理的方法,和事务传播行为 -->
            <tx:method name="save*" propagation="REQUIRED" read-only="false"/>
            <tx:method name="update*" propagation="REQUIRED" read-only="false"/>
            <tx:method name="delete*" propagation="REQUIRED" read-only="false"/>
            <tx:method name="insert*" propagation="REQUIRED" read-only="false"/>
            <tx:method name="get*" read-only="true"/>
            <tx:method name="query*" read-only="true"/>
        </tx:attributes>
    </tx:advice>
</beans>

修改UserService 开启事务

import org.springframework.transaction.annotation.Transactional;

@Transactional
public class UserService {
    UserDao userDao;

修改web.xml

<!--配置环境参数,指定Spring配置文件的位置-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            /WEB-INF/applicationContext.xml
            /WEB-INF/applicationContext_tx.xml
        </param-value>
    </context-param>

九. 增加必填字段check

新增文件UserAction-login-validation.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE validators PUBLIC
        "-//Apache Struts//XWork Validator 1.0.3//EN"
        "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd">
<validators>
    <!-- 非字段校验 -->
    <validator type="requiredstring">
        <param name="fieldName">user.userName</param>
        <message>user.userName不能为空</message>
    </validator>
    <!-- 非字段校验 -->
    <validator type="requiredstring">
        <param name="fieldName">user.password</param>
        <message>user.password不能为空</message>
    </validator>
</validators>

修改struts.xml,增加input

<!-- 登录 返回列表-->
<action name="login" class="com.test.ssh.action.UserAction" method="login" >
    <result name="error">/index.jsp</result>
    <result name="input">/index.jsp</result>
    <result name="userlist" type="redirectAction">getList</result>
</action>

参考资料:
struts2教程
Struts2验证框架

  • 0
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值