Leenham

人生就像舞台,不到谢幕,永远不知道自己有多精彩!

web_chp:bookstore.v3基于SSH框架的网上书店

前言:

其实就是SE的web方面课程的一次作业啦,这是chp要求的网上书店的第三个版本,要求使用SSH框架。

几点说明:我也是因为最近要交作业,所以花在这方面的时间比较多,有一些心得和体会。只是想记下来供以后回顾与琢磨。由于理解局限,难免会有措辞或者观念上的错误,还望指出交流。我也只是在【终于】做完迭代3之后,列列我所做的步骤以及错误处理过程,仅供参考,还望路过者用辩证的眼光来看待。

我的路线是:SSH架构概述===》步骤说明===》举例说明====》常见报错处理办法===》引入他人的工程的注意事项===》个人BB。


######################我是分割线#######################################################################


准备:

1.环境:我的配置是Eclipse Java EE+Tomcat7.0.53

2.需要准备一些SSH架构依赖的jar包,我在网上愣是能找出3、4种不同版本的配置,貌似也不会有什么大问题。(SSH各种版本之间的特性什么的我不懂,我只是找到一份模板,把它WEB-INF/lib文件夹整个“盗用”过来了)。

3.对SSH的理解:SSH=Struts+Hibernate+Spring写之前建议去上网搜一下概念性的文章,初读读不懂很正常,有个大概的了解之后然后再写这次迭代,我相信你大概就能够理解了。关于Spring我看了这篇文章(链接)之后终有体会,特此分享。

简而言之,我的理解是:

(1)Struts相当于分拣器和过滤器,分拣部分将服务器的请求交给特定的action去处理,过滤部分可以拦截对一些资源的访问。当然还有更多的应用,比如对用户是否登录进行处理/*那些部分太高端了,v3版本中我只用了分拣功能*/。

(2)Hibernate用于将实体类和数据库中的表格对应起来,实体类的一个实例就相当于数据表中的一行;

(3)Spring用于注入,差不多可以理解成由xml文件来创建对象,具体描述见上面给出的链接,讲得很清楚。

这里贴下我的代码:点这里,写得一般,不过也算是多提供一份参考代码吧!这是我的界面,拿出来“嘚瑟”一下。


######################我还是分割线#################################################################


步骤:

Step1:写配置文件。Spring的关键文件是applicationContext.xml(在WEB-INF文件夹里面);Hibernate的关键文件是Hibernate.cfg.xml;Struts的关键文件是Struts.xml。然而,由于我写的时候参考的版本里面,把sessionFactory也作为了一个注入对象,所以Hibernate的配置在applicationContext.xml里面就已经通过一个bean完成了,因此我的版本里面没有Hibernate.cfg.xml。如下:

<!--applicationContext.xml-->
<<span style="font-family: Arial, Helvetica, sans-serif;">bean id="candy" class="org.apache.commons.dbcp.BasicDataSource"></span>
		<property name="driverClassName"
			value="com.mysql.jdbc.Driver">
		</property>
		<property name="url"
			value="jdbc:mysql://localhost:3306/ssh_bs"><!-- 需要访问的数据库-->
		</property>
		<property name="username" value="root"></property><!-- 数据库用户名-->
		<property name="password" value=""></property><!-- 数据库密码(这里表示无密码)-->
	</bean>
	<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="candy" /><!-- 在这里注入了datasource-->
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop><!--每当进行更新操作时,如果表不存在或者字段不完整,则将该表填充完整-->
				<prop key="hibernate.show_sql">true</prop><!--在console里面输出执行的sql语句-->
				<prop key="connection.pool_size">1</prop>
			</props>
		</property>
		<property name="mappingResources">
			<list>
				<value>User/user.hbm.xml</value><!--User类与user表映射的配置文件-->
				<value>Order/order.hbm.xml</value><!--Order类与order表映射的配置文件-->
				<value>Book/book.hbm.xml</value><!--Book类与book表映射的配置文件-->
				</list>
		</property>
	</bean>
简单的观察可以知道:这里设置了需要访问的数据库,访问数据库时的一些参数,以及hibernate的配置。见注释。

Struts的配置文件长得都差不多,除了中间<action>标签部分,其他的都应该可以Ctrl+C&Ctrl+V。

【常见错误:1.copy了别人的代码,却连重要的参数都不改,比如数据库的密码是否有,比如配置文件user.hbm.xml会不会被你放到其他的package里面?

2.用了A的的jar包,却用B的代码,然后会报各类ClassNotFound异常......特别麻烦,而且我能够深深体会到配置半天都没有搞出名堂的那种绝望】

Step2:设计实体类。为了完成Hibernate,必须要有实体类。比如我的版本里面有User,Book,Order,需要把它们的属性封装好(即定义私有变量以及这些变量的setter和getter方法)。这里给出一种学来的生成getter、setter代码的方法:

按住Shift+Alt+S键,在下拉菜单中选择"Generate getter and setter",弹出如下图所示界面,然后全选,即可自动生成。(非常方便哟)


Step3:写映射文件。如Book.hbm.xml

<hibernate-mapping package="Book">    
    
    <class name="Book" table="book"> 
    <id name="bid" column="book_id"> 
        <generator class="native"/> 
    </id> 
    <property name="bookname"/> 
    <property name="author"/> 
    <property name="publish_time"/> 
    <property name="publisher"/>
    <property name="price"/>
    <property name="category" />
    <property name="mount"/>
    </class>
    
</hibernate-mapping>

<id>标签标明,Book类中的bid属性,对应于book表格中book_id字段,其中book_id为book表的主键。class=“native”表示这个字段按照数据库的规则设定,默认是auto-incremental。ps:由于前面在applicationContext.xml里面定义过hbm2ddl.auto为update,因此即便数据库里面没有这样一张表,一样可以自动生成。

Step4:写Dao层文件,即我的版本中定义的***Manager.java这些文件,他们都继承自HibernateSupport。在HibernateSupport中有一个私有变量sessionFactory,并定义了它的setter方法。因此在applicationContext.xml中有这样一段代码:

<bean id="bookManager" class="Book.BookManager" abstract="false"                                                    
	lazy-init="default" autowire="default" dependency-check="default">                                              
	<property name="sessionFactory" >                                                                               
		<ref local="sessionFactory"/>                                                                               
	</property>                                                                                                     
</bean>                                                                                                             
表明sessionFactory是由Spring注入的。dao层需要与数据库进行操作,所以每个manager类几乎都要注入sessionFactory。而这个sessionFactory也是之前用bean定义的。在HibernateSupport中规定了getHibernateTemplate()方法,这个方法提供了find、get、save、find方法,其中find方法用来执行hql语句(和sql差不多,不过sql取出来的都是字段,而hql取出来的都是对象),这些接口的好处是你不需要写sql语句,方便经济实惠。一般而言,dao层应该涵括数据对象的增删改查操作。比如,UserManager应该提供user的增加操作(注册用户)、删除操作(注销用户)、改操作(修改信息)、查操作(查询信息)等接口。dao层相当于你的应用和数据库之间的一个概念层,对于应用隐瞒了数据库具体实现的细节。ps:dao=data access object数据访问对象。


step5:写Action文件,即服务器上用于接收、处理请求的模块。每个action想要和数据库交互,得通过红娘(即dao层)牵线。因此,每个需要访问数据库的Action都要有一个dao层的私有变量。而这个变量是通过Spring注入的。见代码:

<bean id="loginAction" class="action.LoginAction"  scope="protoType">  
   <property name="userManager">                                       
       <ref bean="userManager" />                                      
   </property>                                                         
</bean>                                                                
这里的userManager就是负责操作和user有关数据库的一个dao层类。scope=“prototype”表示每次处理请求都要新建一个loginAction对象。而每个对象都ref bean=“userManager”,即都将用到同一个userManager。举例说明的话,在Action里想要存储一个用户到数据库,则需要调用userManager的saveUser方法。

step6:写各种各样的jsp文件,以及设计UI,根据个人喜好或者特色制定。略。


小结:以上是我认为必须要走的6个步骤,不一定要按这个顺序来哦.....


###################华丽丽的分割线,不知不觉写了很多了呢~不等广告了,继续##############################


举例说明:

我将通过实例,讲如何在我之前的配置与实现的基础上,实现登录\注册功能;实现书籍的相关功能。

一、实现登录、注册功能。

先设计User:含有三个属性,用户名、密码、邮箱。定义好User.java后,在user.hbm.xml中:

<hibernate-mapping package="User">    
    
    <class name="User" table="user"> 
    <id name="uid" column="user_id"> 
        <generator class="native"/> 
    </id> 
    <property name="name"/> 
    <property name="password"/> 
    <property name="email"/> 
    </class>
    
</hibernate-mapping>

在配置文件中,UserManager应该<ref bean="sessionFactory" />,而LoginAction应该<ref bean="userManager" />,将相应的属性注入。配置好后开始实现具体细节。

登录需要用用户名和密码到数据库去匹配,因此涉及到dao层(见UserManager.java)。UserManager提供了一个checkUser的函数,该函数的功能是如果数据库存在用户返回该用户,否则返回null。可见,action的任务是:从请求中获取数据后,调用dao层(即UserManager)的checkUser函数即可。代码如下:

public String execute(){
<span style="white-space:pre">	</span>User user = userManager.checkUser(name, password);
		if(user==null)
		{
			userManager.setError("密码不正确");
			System.out.println(userManager.getError());
			return "fail";
		}
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpSession session = request.getSession();
		if(session.getAttribute("username") != null){
			session.removeAttribute("username");
			session.removeAttribute("uid");
		}
		session.setAttribute("username", user.getName());
		session.setAttribute("uid", user.getUid());
		return "success";
}//注:setError不是继承而来的接口,是我自己定义的方法,用于记录session中出现的错误信息。
关于session的这段代码自习研究一下不难得知:这段代码是在将该用户的信息记录到session里面。这样,我们就可以从session中轻轻松松读取到登录用户的信息。

比如在header.jsp中到:

<%
if(!isLogin(session)){
%>
    <li><a href="login.jsp" class="highlight">登录</a><span>|</span></li>				
    <li><a href="regist.jsp" class="highlight">注册</a><span>|</span></li>
<%
}
else{
   %>
   <li class="highlight">当前用户:<%= session.getAttribute("username") %><span> </span></li>
   <li><a href="logout.action" class="highlight">退出</a><span>|</span></li>
   <%
}<span style="font-family: Arial, Helvetica, sans-serif;">%></span>

 isLogin读取了session中的username,判断是否为空,即可确定当前用户是否处于已登录状态。

在struts中我们定义由谁来处理登录的表单。

<action name="loginAction" class="action.LoginAction" method="execute">
	<result>/homepage.jsp</result>
	<result name="fail">/error.jsp</result>
</action>
即,对于向loginAction的请求,服务器将选择action.LoginAction.execute()方法来处理请求。如果execute返回值为“success",即默认值,则将跳转至homepage.jsp,如果为”fail“,则将跳转至error.jsp.而在login.jsp做一个表格就可以完事了。

<!--login.jsp-->
<s:form action="loginAction" method="POST">
<s:textfield label="用户名" name="name"></s:textfield>
<s:password label="密码" name="password"></s:password>
<s:submit value="登录"></s:submit>
</s:form>而在login,jsp

这里使用了struts提供的标签库,据目前我的认识来说,和<form>标签没什么区别,只是使用struts标签库的<s:form>的时候,action=”loginAction",输入框代码如上所示。而在使用<form>的时候,action=“loginAction.action",多加一个.action,输入框格式是<input type="text" name="name" />ps:可以查下html的<form>标签如何使用。在action受理请求时,它有两种方式获取表单中的内容:

1.通过request.getParameter("name")操作,这种方式比较麻烦,而且代码又臭又长(因为可能要做格式转换什么的)。代码应该是这样子的:

HttpServletRequest request = ServletActionContext.getRequest();
String name = request.getParameter("name");
String password = request.getParameter("password");
if(name==null || password==null)
<span style="white-space:pre">	</span>return "fail";
if(userManager.checkUser(name,password)!=null)
<span style="white-space:pre">	</span>return "success";
else
<span style="white-space:pre">	</span>return "fail";

2.通过saction里面的setter方法。比如:在LoginAction里面定义两个私有变量,name,password,定义它们的setter方法(即setName()和setPassword),然后在login里面直接执行UserManager.checkUser(name,password)。注意,这里的name,password都是action的私有变量。

表单在提交的时候,会自动调用setter方法,将action的两个私有变量改成表单要提交的内容(这个过程叫注入。具体原理不要问我,不过貌似确实是这么实现的)。

当然这样太麻烦了。还有更省事的办法,即login.jsp的表单写成这个样子:

<div id="login_box">
	<s:form action="loginAction" method="POST">
	<s:textfield label="用户名" name="user.name"></s:textfield>
	<s:password label="密码" name="user.password"></s:password>
	<s:submit value="登录"></s:submit>
	</s:form>
</div>
就是把name=”name“改成了name="user.name“,这样在提交的时候将name,password作为user的属性,把user整个注入到loginAction中去。因此在action部分也要做相应的改动:定义一个私有变量user,定义setUser方法。然后处理的时候这样写:

public String execute(){
<span style="white-space:pre">	</span>if(userManager.checkUser(user.getName(),user.getPassword())){
<span style="white-space:pre">		</span>return "success";
<span style="white-space:pre">	</span>}
<span style="white-space:pre">	</span>else
<span style="white-space:pre">		</span>return "fail";
}
表单提交的时候会将私有变量设置成表单的内容,所以这个函数里面可以直接使用user。

【常见错误:1.在使用第一种方法的时候,没有import相应的库。2.第二种方法的时候,在loginAction里面,没有定义该私有变量的setter方法,最终会发现自己使用了一个null对象,然后导致报错, NullPointerException什么的。3.第二种方法的时候,使用了struts标签库,却没有加上<%@taglib uri="/struts-tags" prefix="s"%>标签。4.使用<s:form>的时候,其action属性应该直接设置成action的名字,而<form>的时候,action属性应该设置成”actionname.action“。(同理,使用超链接发送GET请求时,也应该在actionname后面加上.action)】以上两种方法都可以用于各个表单的设计中。个人推荐第二种,代码整洁,比较美观,就是如果出了bug会很烦。


------------------------------------------------------------------------------------------------------------------------------------------------------------


同登录一样,注册过程和登陆过程的逻辑几乎是一模一样的。这里我再简短地重新总结一下,回顾一下:

设计regist.jsp的表单,将输入框的name分别设置成user.name,user.password,user.email,action="registAction",然后在struts.xml里面定义registAction:

<!--struts.xml-->
<action name="registAction" class="action.RegistAction" method="execute">
	<result>/login.jsp</result>
	<result name="fail">/error.jsp</result>
</action>
即通过RegistAction这个类的execute方法来处理这个action请求(action.RegistAction表示是action这个package里面的RegistAction)。因此要新建RegistAction类,定义它的execute方法,execute方法可以直接用user对象来表示表单提交上来的内容,因此需要RegistAction类定义一个privavte User user,以及它的setter方法,即User setUser(User user)。RegistAction需要将该用户添加到数据库中,因此需要有一个私有变量userManager。这个变量通过Spring架构的applicationContext.xml文件注入,在applicationContext.xml中加入这样的代码:
<bean id="registAction" class="action.RegistAction"  scope="protoType">
       <property name="userManager">
           <ref bean="userManager" />
       </property>  
    </bean>
通过这段代码,相当于给了RegistAction的userManager一个定义,它再也不是无家可归的null指针啦。接着写具体实现,在userManager.java中新定义一个registUser方法,使用this.getHibernateTemplate().save(user),
//RegistAction.java
public boolean registUser(User user){
	boolean flag = false;
	try{
		this.getHibernateTemplate().save(user);
		flag = true;
	}catch(RuntimeException re){
		throw re;
	}
	return flag ;
}
然后在RegistAction类中添加一个execute方法来处理registAction的请求。在execute中调用userManager.registUser(user) 【注:这个user是由表单注入的,你只要设置了setUser方法,就不需要额外设定这个变量的值啦。】然后运行程序,看能不能符合正常逻辑的运行,理论上应该是可以实现login和regist功能了,接着再debug一下简单的逻辑错误,应该就能正常运行了。

【常见错误:1.复制粘贴别人的代码的时候,把其他功能模块也导入进来了,比如假设你一开始只希望实现注册、登录功能,结果你添加了book.hbm.xml,它发现并没有book这个实体类,然后出错。建议:把和注册、登录无关的代码全部注释掉,很有可能是其他模块不完整报的错误。以上我给的,应该就是一个完整的注册、登录功能所相关的代码了。2.在applicationContext.xml里面,没有对userManager进行注入,导致userManager在使用的时候为null而报错。3.没有打开数据库服务】ps:两点建议:1.在整个逻辑的多个地方使用System.out.println()方法输出关键的变量,运行之后在console里面看是否按照正常的逻辑运行,以及关键的变量是否正确。2.通过console的错误信息,耐心的debug,如果是注册、登录这部分的逻辑问题,参见以上三条,以及重新检查一下代码。如果是其他的报错类型,可能是其他一些常见的错误,在这篇文章最后我会再总结一下。如果还debug不掉,建议把错误信息在搜索引擎上查询一下,你要相信:碰到这种奇葩的报错的,你不是一个人。总会有大神的答案能够解决你的问题。


-------------------------------------------上面的简短地总结一下,“简短”二字简直是在逗我,忘了介绍,我是分割线---------------------------------------------------


2.实现书籍的相关功能。

这个和注册、登录的设计思路几乎也是一样的。需要做的工作有:

1)设计book类,定义book的各个属性

2)写book.hbm.xml映射文件,请仔细检查

3)在applicationContext.xml中,将sessionFactory注入到BookManager中

4)写UI界面的文件,通过form表单或者超链接<a href="addBookAction.action?bid=/*balaba*/>发起相应的请求。

5)在struts里面定义各种book的action,来处理客户端发起的请求

6)实现book的各种action类,或者给一个BookAction类设置多个方法,每个方法用于处理一种请求(我的代码就是这样的)

7)对于每个action类中使用了BookManager的,要在applicationContext.xml中注入,注入方法类于UserManager,(可参考我的代码)

【常见错误:1.第2步中book.hbm.xml和Book实体类不对应,一般会报错说找不到book的balabala属性。2.第5步中忘了添加相应的<action>标签。3.第7步中没有对对BookAction注入bookManager,导致执行的时候bookManager是个null指针。】

--------------------我是分割线,这里插一段小广告,可直接跳过----------------------------------------------------------------------------------------------------------

我能深深理解写这个作业的时候,一个小白的内心,不知道该怎么写,一写要么编译不过,要么跑不过,很心慌,然后弃疗了。

上面我主要讲了:1.我的设计中我要做些什么?2.我写了哪些代码?3.这些代码分别具体有什么作用?如果你发现还是一头雾水,建议边看看代码,边看看我上面给的一些废话,从头再梳理一遍。(ps:请原谅我的表述不清,我尽力了)。

这里我对我之前可能表述不清的地方作一个补述:关于之前提到的各种action分别是什么意思:

总共有个地方涉及到action这个名词:

1.<form>标签中和<s:form>中的 action。无论是<form>和<s:form>标签,内部都有一个action=“actionName”,action是form的一个属性,表示这个表单将被提交到actionName,有actionName来处理这个请求。

2.Struts中的<action>标签。上面1中提到的actionName,即这里的<action name="actionName">中的name。在struts.xml中定义了所有的action,对于一个<action>标签,比如:

<action name="loginAction" class="action.LoginAction" method="execute">
	<result>/homepage.jsp</result>
<span style="white-space:pre">	<result name="fail">/error.jsp</result></span>
</action>

表示,这个action的名字叫做loginAction,这个请求将由【action package】中的【LoginAction类】的【execute方法】来处理。execute方法中,如果注册成功,返回“success”,(默认情况下,<result>标签就是表示返回值为“success”的情况),最终会把homepage.jsp显示给请求者。如果注册失败,execute返回“fail”,最终将把error.jsp显示给请求者看。ps:如果method没有被设定的话,默认是调用该类的execute方法,也就是说这里method=“execute”这段代码是可有可无的。

3.action package:这个是我定义的一个包,名字叫做action,里面包含了负责处理请求的【action类】,因此得名。完全可以改成别的包名,这点没有太大影响。

4.action类:负责处理请求的类,往往是他的一个方法来处理一个请求。比如RegistAction中的unregist方法,用来处理用户退出系统时的请求。通过struts中<action>标签的method可以指定。我定义了很多action类,比如RegistAction,LoginAction,BookAction等等。

广告结束。


----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


涉及到书籍的逻辑可以根据注册和登录的逻辑,依葫芦画葫芦娃。但是,比如我要在首页上显示所有的书籍信息,该怎么办?下面讲讲用struts标签来显示结果集

在homepage.jsp中有这样一段代码,我将解释这段代码的构成:

<s:action name="newBookAction" executeResult="false"></s:action>
<div id="booklist_wrapper">
    <table class="booklist">
    	<tr><th>书名</th><th>作者</th><th>出版社</th><th>类别</th><th>上架时间</th><th>价格</th><th>剩余数量</th><th> </th></tr>
			<s:iterator value="#attr.newBook" status="st">
			<tr>
				<td><s:property value="bookname" /></td>
				<td><s:property value="author"/></td>
				<td><s:property value="publisher"/></td>
				<td><s:property value="category"/></td>
				<td><s:property value="publish_time"/></td>
				<td><s:property value="price"/></td>
				<td><s:property value="mount"/></td>
				<td><a href="addCartItem.action?bid=<s:property value="bid" />&bookname=<s:property value="bookname"/>&publisher=<s:property value="publisher" />&mount=<s:property value="mount" />&price=<s:property value="price" />">加入购物车</a></td>
			</tr>
			</s:iterator>
    </table>
 </div>

这段代码的作用是获取当前数据库中最新的五本书,并把他们用表格的形式显示在homepage.jsp上。

第一行,表示要求执行newBookAction,一般来说执行完一个action都会进行页面跳转,但是这里设置了参数,所以只是单纯地调用BookAction的newBook方法,不会跳转。

第二行—尾行建立一个表格,来显示最新的书。(ps:可以去查查看HTML的<table>标签的格式,这个是比较基础的哦)

在理解<s:iterator>标签之前,看看BookAction的newBook究竟做了些什么:

public String newBook(){
	List<Book>newBook = bookManager.newBook();
	HttpServletRequest request = ServletActionContext.getRequest();
	request.setAttribute("newBook", newBook);
	return "success";
}
即,newBook方法调用dao层的newBook方法,获取到了最新的五本书,并把书的信息放到了newBook这个变量中,然后将这个变量赋给了【request的newBook属性】。axiba,请允许我自我吐槽一下这是什么命名思路,简直让人看不懂。

OK,也就是说,newBook执行的结果就是将最新的五本书放到了request的newBook属性中。

<s:iterator value="#attr.newBook" status="st">
这个标签顾名思义,用于遍历。它要遍历的对象是#attr.newBook,也就是刚刚设置的request的newBook属性的值。

在这个标签中的每行语句,每个遍历的对象都会执行一次。<s:property>标签就是把每一条遍历对象的相关属性显示出来。如代码所示,它被嵌在<td>标签中,因此最后会显示在整个表格中。【注:表格的最后一个字段是一个超链接,用于将这本书添加到购物车。我这里做的操作就是把每本书的信息作为参数放到这个链接里面,这样当我点击这个链接的时候,可以直接把这本书的信息作为参数提交上去,从而实现添加购物车的功能。】

homepage.jsp的最终效果如下:

同理,显示所有用户,显示所有书籍,显示所有购物车条目,显示所有订单信息的时候,用的模式都是这样的。可以依此类推。


###################我是分割线,终于不紧不慢地把举例讲完了########################################


常见错误:

购物车功能、用户的增删改查都是可以复用上面的形式的。比如用户的删除,只需要在UserAction里面新增一个deleteUser方法,在Struts.xml定义一个deleteUserAction,在UserManager添加一个deleteUser方法。

下面讲讲常犯的错误以及一些注意事项:

【1.没有注入dao层的对象。解释:dao层类是和数据库交互的类,每个需要对数据库进行操作的action都要有一个dao层的私有变量,对于LoginAction来说是userManager,对于BookAction来说是bookManager。这些dao层的对象需要通过applicationContext.xml来注入。报错类型:NullPointerException】
【2.在action类中没有定义某个私有变量的setter方法,却直接使用了该私有变量。解释:表单提交的时候,会根据字段找到对应的setter方法并调用,从而将表单的内容注入到action类里面,实现表单内容的提交。否则编译器会认为该私有变量是null。报错类型:NullPointerException】

【3.在struts类里面没有定义action。struts.xml定义了所有的action类,定义了哪个action应该由哪个类的哪个方法去处理该请求,并针对不同的返回值返回不同的页面。报错类型:unknown location】

【4.hbm.xml和实体类不对应。dao层的类通过sessionFactory来访问数据库,sessionFactory通过hbm.xml来将数据库和实体类进行匹配。如果两者不对应,编译器不会知道数据库的表格应该对应于哪个实体类,因此无法创建该bean。报错类型:BeanCreateException。解决方法:审查hbm.xml,看看包名、属性名是否正确】

【5.无法显示查询结果。解释:我最开始的时候写dao层获取新书的newBook方法,写的hql查询语句如下:

String hql = "from book as book where book.mount>0 order by book.publish_time desc";
结果发现:即便数据库中存在对应的项,仍然没有显示任何东西。这是因为,hql里面的对象,应该是实体类,而不是数据表。也就是说,from Book....而不是from book,我只定义了Book类,而没有定义book类,所以找不到数据库中和book类对应的表格,因此不会显示任何结果。按照正常的sql语句应该是from book,不过hql可能比较奇葩,这就是错误的根源所在啊!解决方案:from book 改成from Book】

【6.其他错误,欢迎补充】


##############################################我是分割线####################################


import项目的步骤及过程

我不知道下载别人的项目然后运行是个什么情况,不过我把我的代码成功地在另外一台机器上运行了。

1.下载项目,解压。【获取物品:struts_bs_619】ps:619表示我是6月19号建的工程。

2.打开eclipse,file=>import=>选择“Existing projects into WorkSpace”==>填写根目录“root directory”,选择需要导入的projects,勾选“copy projects into workspace”==》Finish

3.试着运行【右键项目=》Run As=》Run on Server】,如果不能跑,那么【右键项目=》property=》Java Build Path=》选中JRE System Library=》Edit=》选取jre】;


如果还不能运行,检测一下服务器的状态,或者新建一个服务器。如果还有问题,上网查查其他方法吧TAT。


##############################我是分割线####################################################


个人总结:

以前写代码从来没有用过什么框架的,而且这次也才仅仅是第二次用java语言写项目,还是写web项目,挺痛苦的。

最后重申一下,这个不过就是我们学习过程中一次作业啦!看不懂我上面给的超多说明没关系。我也只不过写了一些关于这次作业的个人总结而已。





阅读更多
个人分类: 作业小结
上一篇web_chp:bookstore.v1作业小结
想对作者说点什么? 我来说一句

BookStore源码

2015年04月27日 345KB 下载

基于SSH框架网上书店系统

2016年01月02日 14.38MB 下载

基于SSH网上书店系统

2015年04月16日 17.21MB 下载

基于ssh网上书店

2014年04月19日 3.84MB 下载

SSH网上书店

2015年06月19日 17.82MB 下载

没有更多推荐了,返回首页

关闭
关闭