SSH(struts+spring+hibernate)框架搭建流程

本文介绍了SSH(Struts+Spring+Hibernate)框架的搭建过程,强调了每个组件的作用。Struts负责前端请求与后端处理的交互,Hibernate用于对象关系映射,Spring提供依赖注入以实现解耦。在配置过程中,详细讲解了web.xml、struts.xml、spring配置文件以及数据库相关配置。同时,文章指出对Spring的理解仍不深入,尤其是其在MVC模式中的作用,以及遇到的一个关于SessionFactory初始化失败的bug。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接触ssh大约一学期,已经算是会用然而并不是很懂其中的原理,虽然寒假有在看框架方面的书,但仍然一知半解。作为一个强迫症,用的时候不明白原理简直觉得生无可恋。嗯但总归要一步步来,用了一天多的时间自己搭出了整个环境框架,毕竟还要和它打交道两年,不急不急~

引入各个包的步骤见下面这个网址,其中第四步引入Struts2.1包的时候,需要选中下面两个包而不是只有核心包。下面这个包里面包含了struts2-spring-plugin,可以将struts和spring整合起来的。

嗯,根据这个网站进行到第四步就好了后面的不用看。引入包这种其实应该也可以自己在官网下载然后导入项目,毕竟这种自带的感觉比较老。


接下来就是各种配置文件了,按照启动顺序来讲吧,服务器启动之后会自动加载web.xml这个文件,可以在这里配置网站的首页界面,一些监听器过滤器等。

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>	
  <!-- 程序的入口界面 -->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <!-- spring的监听器,在web应用启动的时候自动根据context-param中的路径创建spring -->
  <!-- 加入了struts2-spring-plugin之后 如果不加这个监听器就会404,不明白 -->
    <context-param>
  	<param-name>contextConfigLocation</param-name>
	<param-value>WEB-INF/applicationContext.xml</param-value>
  </context-param> 
  <listener>
  	<listener-class>
  		org.springframework.web.context.ContextLoaderListener
  	</listener-class>
  </listener>
    
   <!-- 设置struts的过滤器 -->
  <filter>
  	<filter-name>struts2</filter-name>
  	<filter-class>
  		org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter
  	</filter-class>
  </filter>
  <filter-mapping>
  	<filter-name>struts2</filter-name>
  	<url-pattern>/*</url-pattern>   <!-- 不能改为 /*.action!!! -->
  </filter-mapping>
 </web-app>

index.jsp是访问网站后第一个界面,写的很简单,就一个用户名,密码。

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
    
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
    
 <body>
			<form id="login" method="get" action="Login">
				<label>用户名</label>
				<input type="text" name="user.name" />
				<label>密码</label>
				<input type="password" name="user.password"  />
				<input type="submit" value="提交"/>
			</form> 
  </body>

</html>

这里说一下利用struts传输数据的方式

在这个页面中input里规定了name是user.name 和 user.password ,user是一个程序中的自定义类,name和password都是它的属性,这个类我定义在了com.A.domain中。当用户点击提交后,struts会在它的配置文件struct.xml 中查找action为Login配置,找到相应的处理类和处理方法,并且这个处理类中会有user属性,因为我在前端界面中获取到了用户输入的user.name和user.password,这时候的后端user属性就自动拿到了前端用户输入的值,然后可以进行处理。

后端向前端传输数据也是一样的,后端从数据库中获取数据,比如获取一个user类,这时候根据struts.xml中的配置会转向一个新的jsp,在这个新的jsp中直接用struts中自带的param标签就可以显示user中的值。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd">
<struts>

    
<constant name="struts.devMode" value="true" />

   <package name="loginmanage" extends="struts-default">
      <action name="Login"  class="com.A.web.LoginAction"  method="Login">
            <result name="success">/views/MyJsp.jsp</result>
      </action>
   </package>
   
</struts>

struts.xml配置文件就是上面这个,当LoginAction中的Login方法处理完返回值是success的时候,页面跳转到MyJsp.jsp。

后端处理的时候是一层层调用的,action会调用service,service调用dao层,dao层是和数据库打交道的,实现数据库的增删改查,这个交给hibernate来做,这是一个将关系数据库映射为自定义对象的一个框架,支持程序员用面向对象的思维来和数据库交互。至于service层存在的意义我目前并没有想明白 233。

嗯那么spring用来干什么呢,我目前的理解是spring是用来解耦的。正常来讲我有一个action,现在action会调用service,那么service的实例化会交给action来做,有了spring之后就可以根据spring的依赖注入由spring创建service,这样后续要更改的时候只需要更改spring配置文件而不用动程序。所以讲道理spring似乎就是一个配置文件,这个配置文件管理着各种类之间的创建关系。hibernate和spring整合的话一些和数据库有关的配置如sessionFactory,hbm.xml位置等这些也就交给了spring。

<?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:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<bean id="dataSource"
	    class="org.apache.commons.dbcp.BasicDataSource">
	    <property name="driverClassName"
	      value="com.mysql.jdbc.Driver">
	    </property>
	 	 	<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
	        <property name="username" value="root"></property>
	        <property name="password" value="root"></property>
	</bean> 
  
  <bean id="sessionFactory"
    class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
    <property name="dataSource">
      <ref bean="dataSource" />
    </property>

    <property name="hibernateProperties">
      <props>
        <prop key="hibernate.dialect">
          org.hibernate.dialect.MySQLDialect
        </prop>
        <prop key="hibernate.connection.autocommit">true</prop>
        <prop key="hibernate.show_sql">false</prop>
        <prop key="hibernate.enable_lazy_load_no_trans">true</prop>
      </props>
    </property>
    
    <property name="mappingResources">
      <list>
        <value>
          com/A/domain/User.hbm.xml
        </value>
	  </list>
    </property>
   </bean>
    
    <bean id="LoginDAO" class="com.A.dao.impl.LoginDao">
    	<property name="sessionFactory">  <ref bean="sessionFactory" />  </property>
    </bean>
    
    <bean id="LoginService" class="com.A.service.impl.LoginService">
    	 <property name="loginDao">  <ref bean="LoginDAO" />  </property> 
    </bean>
    
    <bean id="LoginAction" class="com.A.web.LoginAction" scope="request">
    	<property name="loginService">  <ref bean="LoginService" />  </property>
    </bean>

</beans>
spring的配置文件applicationContext.xml见上,在web中我们创建了ContextLoaderListener这个监听类,在web一开始启动的 时候,这个类会监听到然后根据 applicationContext.xml中的内容创建各个实例,其中scope=“request”表明该实例的范围,每次有一个 新访问的时候都会创建一遍,默认的话是单例的,只创建一次。property name的值是和get set函数名有关的,去掉get set剩下的部分, 但是还要注意大小写的问题。

sessionFactory datasource都是和数据库相关的配置,User.hbm.xml是定义 数据库中的数据表 和 程序中自定义类 对应关系的配置文件,要在spring中写明它的位置。

嗯,上面所有的配置文件就都齐了,接下来就是action service dao层具体类的编写了。service和dao层都要有一个接口类,一个实现类,然后所有的定义都是以接口定义的,面向接口编程,ioc注入完成,不过我还不明白具体是怎么样的。

我比较奇怪的是下面这个,action层中service的get函数,要处理service为空的情况,利用反射创建。但是service层的dao类并不需要这样做,直接get就好了,也没有处理为空的情况。

	public ILoginService getLoginService() {
		 if (loginService == null) {
	            ServletContext sc = ServletActionContext.getServletContext();
	            ApplicationContext ac = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
	            loginService = (ILoginService) ac.getBean("LoginService");
	        }
		return loginService;
	}

嗯大致目前只能理解到这里了,主要就是spring还是不太懂,MVC模式理解的也不透彻,大概还是too young

以及还有一个bug没解决:= =

Error creating bean with name 'sessionFactory' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.hibernate.HibernateException: 'hibernate.dialect' must be set when no Connection avalable

更新:上面这个bug在实验室的电脑上是正常的,dialect我确实也已经设置了且applicationContext.xml是可以正确加载的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值