Chinaunix首页 | 论坛 | 博客
  • 博客访问: 392374
  • 博文数量: 5
  • 博客积分: 7010
  • 博客等级: 少将
  • 技术积分: 1315
  • 用 户 组: 普通用户
  • 注册时间: 2006-04-18 12:30
文章分类

全部博文(5)

文章存档

2009年(1)

2008年(4)

我的朋友
最近访客

分类: Java

2008-08-25 21:31:48

近日公司来了一新同事,娘西,<小样,新来的>,来了一个月左右,叫他学习框架知识.最后写了一WSH的用户添/删/
 
改/查的工程.在过程中有很多问题,一些细的的问题.报错了,让我调啊调.我也很撮的.只是查询网上的资料看.看
 
帖子.在过程中我记录了一些细节的东西,也是很容易报错的地方..供大家参考,饮水思源..
 
webwork(webwork 2.2):
 
1.这里首先要讲的是 WebWork2.2新特性,使用FreeMarker的FTL做装饰页面,所以呢在页面上使用UI标
 
签,webwork会自动的使用FreeMarker的ftl.
 
在webwork.properites文件中呢有一个webwork.ui.theme = XXX属性,这一项呢就是配置自定义的ftl的.
 
就是配置主题啦,详细的可以看webwork的中文文档,里面很详细.
 
自定义主题:比如说呢
 
##webwork.ui.theme = gem 
 
##webwork2的标签默认使用的ftl模板;如果配置webwork.ui.theme =gem,表示 /template/gem目录,
 
在这个目录下重新覆盖ftl..
 
不然会报出
 
java.io.FileNotFoundException: Template /template/gem/form.ftl not found.

 at freemarker.template.Configuration.getTemplate(Configuration.java:489)

 at freemarker.template.Configuration.getTemplate(Configuration.java:452)
 
的信息让你摸不着头脑.
 
 
 
 
 
 
Spring 报错:
 
1.当服务器启动时控制台报
 
严重: Error listenerStart

2008-8-25 20:55:12 org.apache.catalina.core.StandardContext start

严重: Context startup failed due to previous errors
 
这样是没有什么实际意义的,只是说明spring 配置文件错误..
 
这里呢可以打开服务器(Tomcat,Weblogic,.....)的日志,日志里会有详细的报错信息
 
Tomcat:%Tomcat_home%/logs/localhost_log.2008-06-17.txt的日志..08-06-17当天
 
Weblogic:%wl_home%\user_projects\domains\mydomain\myserver\myserver.log
 
 
2.事务控制
 
 
   class="com.webwork.cy.util.springframework.autoproxy.BeanTypeAutoProxyCreator">
  
   
  

  
   com.webwork.cy.biz.*Biz
  

 

 
 
 
  
  
   
    PROPAGATION_REQUIRED,readOnly
    PROPAGATION_REQUIRED,readOnly
    PROPAGATION_REQUIRED
    PROPAGATION_REQUIRED
    PROPAGATION_REQUIRED
    PROPAGATION_REQUIRED
   

  

 
 
com.webwork.cy.util.springframework.autoproxy.BeanTypeAutoProxyCreator
 
这个是自己写的一个类,实现AbstractAutoProxyCreator,功能和BeanNameAutoProxyCreator相似,这
 
里就不贴出来了,如果谁有需要,可以M我.
 
 
 
hibernate:
 
1. 事务
 
Session session = sessionFactory.openSession();
 
Transaction tx = session.beginTransaction();
 
session.save(customer);//之前已实例化好了的一个对象
 
tx.commit();
 
…………………………………………………………………………
 
示例很简单,就是向数据库中插入一条顾客信息,这是一个最简单的数据库事务。在这个简单的过程中,
 
Hibernate为我们做了一些什么事情呢?
 
为了更好的观察,我们将Hibernate的”show_sql”属性设置为true,然后运行我们的程序,控制台打印出
 
如下信息:
 
Hibernate: select max(ID) from CUSTOMER
Hibernate: insert into CUSTOMER (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, description, BIRTHDAY, REGISTERED_TIME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
 
这里也许看不出什么端倪来,现在在session.save(customer)后面加一行代码,输出这个customer的
 
OID,System.out.println(customer.getId()),
 
再次运行程序,控制台输出为:
 
Hibernate: select max(ID) from CUSTOMER
22
Hibernate: insert into CUSTOMER (NAME, EMAIL, PASSWORD, PHONE, ADDRESS, SEX, IS_MARRIED, description, BIRTHDAY, REGISTERED_TIME, ID) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
 
OID在insert语句之前输出,这可以说明两个问题:1.insert语句并不是在执行save的时候发送给数据库
 
的;2.insert语句是在执行commit的时候发送给数据库的。
 
结合前面我们所说过的:执行save的时候,Hibernate会首先把对象放入缓存,然后计划一条insert语句。
 
一个基本的插入流程就出来了:
 
1.  判断所要保存的实例是否已处于持久化状态,如果不是,则将其置入缓存;
 
2.  根据所要保存的实例计划一条insert sql语句,注意只是计划,并不执行;
 
3.  事务提交时执行之前所计划的insert语句;
 
后台还打印出了select max(ID) from CUSTOMER,这主要是为了给customer赋予一个OID,因为一般情
 
况下临时对象的OID是NULL。
 
接着我们做两个测试:
 
1.  将tx.commit();注释掉,此时控制台没有打印出insert语句;
 
2.  将tx.commit()换成session.flush,此时控制太打印出了insert语句,但是数据库中并没有添加新
 
的记录;
 
通过查阅Hibernate的API可以知道flush方法的主要作用就是清理缓存,强制数据库
 
与Hibernate缓存同步,以保证数据的一致性。它的主要动作就是向数据库发送一系列的sql语句,并执行这
 
些sql语句,但是不会向数据库提交。
 
而commit方法则会首先调用flush方法,然后提交事务。这就是为什么我们仅仅调用flush的时候记录并未插
 
入到数据库中的原因,因为只有提交了事务,
 
对数据库所做的更新才会被保存下来。因为commit方法隐式的调用了flush,所以一般我们都不会显示的调用
 
flush方法。
 
 
2.待续
----------------------------------------------------------
2008-09-12更新
 
问题情况,当输入查询条件的时候报
 
org.springframework.orm.hibernate3.HibernateJdbcException:JDBC exception on Hibernate data access; nested exception is org.hibernate.exception.DataException: could not execute query
 
 
rg.springframework.orm.hibernate3.HibernateJdbcException: JDBC exception on Hibernate data access; nested exception is org.hibernate.exception.DataException: could not execute query
Caused by: org.hibernate.exception.DataException: could not execute query
	at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:75)
	at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
	at org.hibernate.loader.Loader.doList(Loader.java(Compiled Code))
	at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java(Inlined Compiled Code))
	at org.hibernate.loader.Loader.list(Loader.java(Compiled Code))
	at org.hibernate.loader.criteria.CriteriaLoader.list(CriteriaLoader.java(Inlined Compiled Code))
	at org.hibernate.impl.SessionImpl.list(SessionImpl.java(Compiled Code))
	at org.hibernate.impl.CriteriaImpl.list(CriteriaImpl.java(Compiled Code))
	at com.skyon.mica.util.dao.hibernate.HibernateBaseDao.find(HibernateBaseDao.java:132)
	at sun.reflect.GeneratedMethodAccessor273.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java(Compiled Code))
	at java.lang.reflect.Method.invoke(Method.java(Compiled Code))
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java(Compiled Code))
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java(Inlined Compiled Code))
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java(Compiled Code))
	at org.springframework.orm.hibernate3.HibernateInterceptor.invoke(HibernateInterceptor.java(Compiled Code))
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java(Compiled Code))
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java(Compiled Code))
	at $Proxy130.find(Unknown Source)
	at com.skyon.mica.frontage.contract.manager.standard.StandardContractManager.getContract(StandardContractManager.java:144)
	at sun.reflect.GeneratedMethodAccessor660.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java(Compiled Code))
	at java.lang.reflect.Method.invoke(Method.java(Compiled Code))
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java(Compiled Code))
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java(Inlined Compiled Code))
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java(Compiled Code))
	at com.skyon.mica.rule.intercept.MethodRuleInterceptor.invoke(MethodRuleInterceptor.java:51)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java(Compiled Code))
	at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java(Compiled Code))
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java(Compiled Code))
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java(Compiled Code))
	at $Proxy215.getContract(Unknown Source)
	at com.skyon.mica.frontage.loanDueBill.web.action.LoanDueBillMaintenanceAction.showLoanDueBill(LoanDueBillMaintenanceAction.java:225)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java(Compiled Code))
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java(Compiled Code))
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java(Compiled Code))
	at java.lang.reflect.Method.invoke(Method.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:365)
	at com.opensymphony.xwork.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java(Inlined Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.DefaultWorkflowInterceptor.doIntercept(DefaultWorkflowInterceptor.java:137)
	at com.opensymphony.xwork.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.validator.ValidationInterceptor.doIntercept(ValidationInterceptor.java:115)
	at com.opensymphony.xwork.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.webwork.interceptor.FileUploadInterceptor.intercept(FileUploadInterceptor.java:171)
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.I18nInterceptor.intercept(I18nInterceptor.java:151)
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.AroundInterceptor.intercept(AroundInterceptor.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.skyon.mica.util.web.webwork.ExceptionToActionErrorInterceptor.intercept(ExceptionToActionErrorInterceptor.java:45)
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:100)
	at com.opensymphony.xwork.DefaultActionInvocation.invoke(DefaultActionInvocation.java(Compiled Code))
	at com.opensymphony.xwork.DefaultActionProxy.execute(DefaultActionProxy.java:113)
	at com.opensymphony.webwork.dispatcher.DispatcherUtils.serviceAction(DispatcherUtils.java:233)
	at com.opensymphony.webwork.dispatcher.FilterDispatcher.doFilter(FilterDispatcher.java(Compiled Code))
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java(Compiled Code))
	at com.opensymphony.module.sitemesh.filter.PageFilter.parsePage(PageFilter.java:118)
	at com.opensymphony.module.sitemesh.filter.PageFilter.doFilter(PageFilter.java:52)
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java(Compiled Code))
	at com.opensymphony.webwork.dispatcher.ActionContextCleanUp.doFilter(ActionContextCleanUp.java(Compiled Code))
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java(Compiled Code))
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java(Compiled Code))
	at org.acegisecurity.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java(Compiled Code))
	at org.acegisecurity.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java(Compiled Code))
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java(Compiled Code))
	at org.acegisecurity.ui.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java(Compiled Code))
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java(Compiled Code))
	at org.acegisecurity.wrapper.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java(Compiled Code))
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java(Compiled Code))
	at org.acegisecurity.ui.AbstractProcessingFilter.doFilter(AbstractProcessingFilter.java(Compiled Code))
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java(Compiled Code))
	at org.acegisecurity.ui.logout.LogoutFilter.doFilter(LogoutFilter.java(Compiled Code))
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java(Compiled Code))
	at org.acegisecurity.context.HttpSessionContextIntegrationFilter.doFilter(HttpSessionContextIntegrationFilter.java(Compiled Code))
	at org.acegisecurity.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java(Compiled Code))
	at org.acegisecurity.util.FilterChainProxy.doFilter(FilterChainProxy.java(Compiled Code))
	at org.acegisecurity.util.FilterToBeanProxy.doFilter(FilterToBeanProxy.java(Compiled Code))
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java(Compiled Code))
	at org.springframework.orm.hibernate3.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java(Compiled Code))
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java(Compiled Code))
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java(Compiled Code))
	at com.skyon.mica.util.web.webwork.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java(Compiled Code))
	at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java(Compiled Code))
	at weblogic.servlet.internal.FilterChainImpl.doFilter(FilterChainImpl.java(Inlined Compiled Code))
	at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java(Compiled Code))
	at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java(Compiled Code))
	at weblogic.security.service.SecurityManager.runAs(SecurityManager.java(Inlined Compiled Code))
	at weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java(Compiled Code))
	at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java(Compiled Code))
	at weblogic.kernel.ExecuteThread.execute(ExecuteThread.java(Compiled Code))
	at weblogic.kernel.ExecuteThread.run(ExecuteThread.java(Compiled Code))
Caused by: com.ibm.db2.jcc.a.SqlException: DB2 SQL error: SQLCODE: -302, SQLSTATE: 22001, SQLERRMC: null
	at com.ibm.db2.jcc.a.hd.e(hd.java(Compiled Code))
	at com.ibm.db2.jcc.a.hd.a(hd.java(Compiled Code))
	at com.ibm.db2.jcc.c.jb.o(jb.java:655)
	at com.ibm.db2.jcc.c.jb.j(jb.java(Compiled Code))
	at com.ibm.db2.jcc.c.jb.c(jb.java(Compiled Code))
	at com.ibm.db2.jcc.c.w.c(w.java(Inlined Compiled Code))
	at com.ibm.db2.jcc.c.cc.h(cc.java(Compiled Code))
	at com.ibm.db2.jcc.a.hd.p(hd.java(Inlined Compiled Code))
	at com.ibm.db2.jcc.a.id.d(id.java(Compiled Code))
	at com.ibm.db2.jcc.a.id.X(id.java(Compiled Code))
	at com.ibm.db2.jcc.a.id.executeQuery(id.java(Compiled Code))
	at weblogic.jdbc.wrapper.PreparedStatement.executeQuery(PreparedStatement.java(Compiled Code))
	at org.hibernate.jdbc.AbstractBatcher.getResultSet(AbstractBatcher.java(Compiled Code))
	at org.hibernate.loader.Loader.getResultSet(Loader.java(Compiled Code))
	at org.hibernate.loader.Loader.doQuery(Loader.java(Compiled Code))
	at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java(Compiled Code))
	... 108 more
-----------
发现输入主变量的值对于其在 SELECT、VALUES 
或预编译语句中的使用来说太大。发生下列其中一种情况:
o SQL 语句中使用的相应主变量或参数标记被定义为字符串,但是输入主
    变量包含的字符串太长。
o SQL 语句中使用的相应主变量或参数标记被定义为数字,但是输入主变
    量包含的数值太大。
o C 语言以 NUL 终止的字符串主变量中丢失终止字符 NUL。
o 联合系统用户:在 联通 会话中,可能已违反特定于数据源的限制。
由于在 EXECUTE 或 OPEN 语句上的 SQLDA 
中指定了不正确的主变量或不正确的 SQLLEN 值,所以发生此错误。
不能处理该语句。
用户响应:
确保输入主变量值的类型和长度是正确的。若输入主变量向参数标记提供值
,则使这些值与参数标记的隐含数据类型和长度相匹配。
联合系统用户:对于 联通 会话,确定哪一个数据源导致该错误(请参阅
Problem determination
guide,以了解标识失败数据源所要遵循的过程)。检查该数据源的 SQL
对话以确定违反了哪个特定限制,并根据需要来调整限制。
 sqlcode : -302
 sqlstate : 22001, 22003
------------------------------------------------------------------------------------------------
由此看来这个输入的查询条件错误
但页面已经做了判断.为什么还会出现这样的情况呢?
想到页面输入的时候用全码输入数字或者输中文字符,它们的字节码长度可能就会大于数据中定义的长度.
输入:"1234567890123456" 及输入中文测试,
所以报出的错误是一样的,证明已找到出错的原因
------------------------------------------------------------------------------------------------
但是在用工具查询的时候如:
 //CUSTOM_BIT 为char(1)
 select CUSTOM_BIT from product where CUSTOM_BIT='11111111111111'
这样后台是不会出错的,那这是为什么呢?为此又做测试
------------------------------------------------------------------------------------------------
//程序片断,当执行如下程序
public void Query() {
  try {
   //初始化数据库连接
   this.in();
   psm = con.prepareStatement("select CUSTOM_BIT from product where CUSTOM_BIT=?");
   //CUSTOM_BIT字段为char(1),这里设值0是没有问题的.但是改成两位.在执行查询的时候就会报302的问题
   psm.setString(1, "0");
   //psm.setString(1, "01");
   rs = psm.executeQuery();
   while (rs.next()) {
    System.out.println(rs.getString(1));
   }
  } catch (Exception eq) {
   eq.printStackTrace();
  } finally {
   this.closedate();
  }
 }
------------------------------------------------------------------------------------------------
而hibernate也是用这种方式去设置查询条件的..
 而Statement和PreparedStatement之间的也有区别的,前者是执行完整的sql语句;后者是使用于定义格式,将sql中的where部分参数化,
 对于大量相同的sql语句的执行,后者的效率高,而且可以防止sql注入,如 'userName or 1=1'将会被截断,与Statement都是真的.
所以当设置值的时候,PreparedStatement会判断输入的值是否超过数据库相应字段的长度,抛出错误.
发现输入主变量的值对于其在 SELECT、VALUES 或预编译语句中的使用来说太大
----------------------------------------------------------
 


 
 
 
 
 
阅读(2065) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~