您的位置:首页 > 编程语言 > Java开发

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

2017-03-20 16:38 585 查看
接触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"
xml
4000
ns: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是可以正确加载的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: