The NoteBook of EricKong

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  611 Posts :: 1 Stories :: 190 Comments :: 0 Trackbacks

#

要想成功访问 SQL Server 数据库中的数据, 我们需要两个方面的授权:一、获得准许连接 SQL Server 服务器的权利; 二、获得访问特定数据库中数据的权利(select, update, delete, create table ...)。 假设,我们准备建立一个 dba 数据库帐户,用来管理数据库 mydb。

1. 首先在 SQL Server 服务器级别,创建登陆帐户(create login)

create login dba with password='sqlstudy', default_database=mydb

登陆帐户名为:“dba”,登陆密码:“sqlstudy”,默认连接到的数据库:“mydb”。 这时候,dba 帐户就可以连接到 SQL Server 服务器上了。但是此时还不能 访问数据库中的对象(严格的说,此时 dba 帐户默认是 guest 数据库用户身份, 可以访问 guest 能够访问的数据库对象)。

要使 dba 帐户能够在 mydb 数据库中访问自己需要的对象, 需要在数据库 mydb 中建立一个“数据库用户”,赋予这个“数据库用户” 某些访问权限,并且把登陆帐户“dba” 和这个“数据库用户” 映射起来。 习惯上,“数据库用户” 的名字和 “登陆帐户”的名字相同,即:“dba”。 创建“数据库用户”和建立映射关系只需要一步即可完成:

2. 创建数据库用户(create user):

create user dba for login dba with default_schema=dbo

并指定数据库用户“dba” 的默认 schema 是“dbo”。这意味着 用户“dba” 在执行“select * from t”,实际上执行的是 “select * from dbo.t”。

3. 通过加入数据库角色,赋予数据库用户“dba”权限:

exec sp_addrolemember 'db_owner', 'dba'

此时,dba 就可以全权管理数据库 mydb 中的对象了。

如果想让 SQL Server 登陆帐户“dba”访问多个数据库,比如 mydb2。 可以让 sa 执行下面的语句:

use mydb2
go

create user dba for login dba with default_schema=dbo
go

exec sp_addrolemember 'db_owner', 'dba'
go

此时,dba 就可以有两个数据库 mydb, mydb2 的管理权限了!

4. 禁用、启用登陆帐户:

alter login dba disable
alter login dba enable

5. 登陆帐户改名:

alter login dba with name=dba_tom

提示:在 SQL Server 2005 中也可以给 sa 改名。 《SQL Server 2005 安全性增强:给超级用户 sa 改名》

6. 登陆帐户改密码:

alter login dba with password='sqlstudy.com'

7. 数据库用户改名:

alter user dba with name=dba_tom

8. 更改数据库用户 defult_schema:

alter user dba with default_schema=sales

9. 删除数据库用户:

drop user dba

10. 删除 SQL Server登陆帐户:

drop login dba
posted @ 2010-06-28 21:56 Eric_jiang 阅读(510) | 评论 (0)编辑 收藏

其实这个异常写的非常之清楚,就是会话关闭,无法对Hibernate实体进行操作。造成这样的情况有很多,什么书写错误啊,逻辑错误 啊,等等.不过,偶是因为LAZY.

关 于lazy机制:

延迟初始化错误是运用Hibernate开发项目时最常见的错误。如果对一个类或者集合配置了延迟检 索策略,那么必须当代理类实例或代理集合处于持久化状态(即处于Session范围内)时,才能初始化它。如果在游离状态时才初始化它,就会产生延迟初始 化错误。

下面把Customer.hbm.xml文件的<class>元素的lazy属性设为true,表示使用延迟检索策略:

<class name="mypack.Customer" table="CUSTOMERS" lazy="true">

当执行Session的load()方法时,Hibernate不会立即执行查询CUSTOMERS表的select语句,仅仅返回 Customer类的代理类的实例,这个代理类具由以下特征:

(1) 由Hibernate在运行时动态生成,它扩展了Customer类,因此它继承了Customer类的所有属性和方法,但它的实现对于应用程序是透明 的。
(2) 当Hibernate创建Customer代理类实例时,仅仅初始化了它的OID属性,其他属性都为null,因此这个代理类实例占用的内存很少。
(3)当应用程序第一次访问Customer代理类实例时(例如调用customer.getXXX()或customer.setXXX()方法), Hibernate会初始化代理类实例,在初始化过程中执行select语句,真正从数据库中加载Customer对象的所有数据。但有个例外,那就是当 应用程序访问Customer代理类实例的getId()方法时,Hibernate不会初始化代理类实例,因为在创建代理类实例时OID就存在了,不必 到数据库中去查询。

提示:Hibernate采用CGLIB工具来生成持久化类的代理类。CGLIB是一个功能强大的Java字节码生成工具,它能够在程 序运行时动态生成扩展 Java类或者实现Java接口的代理类。关于CGLIB的更多知识,请参考:

http://cglib.sourceforge.net/。

以下代码先通过Session的load()方法加载Customer对象,然后访问它的name属性:

tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
customer.getName();
tx.commit();

在运行session.load()方法时Hibernate不执行任何select语句,仅仅返回Customer类的代理类的实 例,它的OID为1,这是由load()方法的第二个参数指定的。当应用程序调用customer.getName()方法时,Hibernate会初始 化Customer代理类实例,从数据库中加载Customer对象的数据,执行以下select语句:

select * from CUSTOMERS where ID=1;
select * from ORDERS where CUSTOMER_ID=1;

当<class>元素的lazy属性为true,会影响Session的load()方法的各种运行时行为,下面举例说 明。

1.如果加载的Customer对象在数据库中不存在,Session的load()方法不会抛出异常,只有当运行 customer.getName()方法时才会抛出以下异常:

ERROR LazyInitializer:63 - Exception initializing proxy
net.sf.hibernate.ObjectNotFoundException: No row with the given identifier exists: 1, of class:
mypack.Customer

2.如果在整个Session范围内,应用程序没有访问过Customer对象,那么Customer代理类的实例一直不会被初始 化,Hibernate不会执行任何select语句。以下代码试图在关闭Session后访问Customer游离对象:

tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
tx.commit();
session.close();
customer.getName();

由于引用变量customer引用的Customer代理类的实例在Session范围内始终没有被初始化,因此在执行 customer.getName()方法时,Hibernate会抛出以下异常:

ERROR LazyInitializer:63 - Exception initializing proxy
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed

由此可见,Customer代理类的实例只有在当前Session范围内才能被初始化。

3.net.sf.hibernate.Hibernate类的initialize()静态方法用于在Session范围内显式初始 化代理类实例,isInitialized()方法用于判断代理类实例是否已经被初始化。例如:

tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
if(!Hibernate.isInitialized(customer))
Hibernate.initialize(customer);
tx.commit();
session.close();
customer.getName();

以上代码在Session范围内通过Hibernate类的initialize()方法显式初始化了Customer代理类实例,因 此当Session关闭后,可以正常访问Customer游离对象。

4.当应用程序访问代理类实例的getId()方法时,不会触发Hibernate初始化代理类实例的行为,例如:

tx = session.beginTransaction();
Customer customer=(Customer)session.load(Customer.class,new Long(1));
customer.getId();
tx.commit();
session.close();
customer.getName();

当应用程序访问customer.getId()方法时,该方法直接返回Customer代理类实例的OID值,无需查询数据库。由于 引用变量 customer始终引用的是没有被初始化的Customer代理类实例,因此当Session关闭后再执行customer.getName()方法, Hibernate会抛出以下异常:

ERROR LazyInitializer:63 - Exception initializing proxy
net.sf.hibernate.HibernateException: Could not initialize proxy - the owning Session was closed


解决方法:

由于hibernate采用了lazy=true,这样当你用hibernate查询时,返回实际为利用cglib增强的代理类,但其并没有实际填 充;当你在前端,利用它来取值(getXXX)时,这时Hibernate才会到数据库执行查询,并填充对象,但此时如果和这个代理类相关的 session已关闭掉,就会产生种错误.
在做一对多时,有时会出现"could not initialize proxy - clothe owning Session was sed,这个好像是hibernate的缓存问题.问题解决:需要在<many-to-one>里设置lazy="false". 但有可能会引发另一个异常叫

failed to lazily initialize a collection of role: XXXXXXXX, no session or session was closed

此异常解决方案请察看本人博客(http://hi.baidu.com/kekemao1)的Hibernate异常中的《failed to lazily initialize a collection of role异常》

?
解决方法:在web.xml中加入
<filter>
    <filter-name>hibernateFilter</filter-name>
    <filter-class>
     org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
    </filter-class>
</filter
<filter-mapping>
    <filter-name>hibernateFilter</filter-name>
    <url-pattern>*.do</url-pattern>
</filter-mapping>
就可以了;

参考了:
Hibernate与延迟加载:

Hibernate对象关系映射提供延迟的与非延迟的对象初始化。非延迟加载在读取一个对象的时候会将与这个对象所有相关的其他对象一起读取出来。 这有时会导致成百的(如果不是成千的话)select语句在读取对象的时候执行。这个问题有时出现在使用双向关系的时候,经常会导致整个数据库都在初始化 的阶段被读出来了。当然,你可以不厌其烦地检查每一个对象与其他对象的关系,并把那些最昂贵的删除,但是到最后,我们可能会因此失去了本想在ORM工具中 获得的便利。


一个明显的解决方法是使用Hibernate提供的延迟加载机制。这种初始化策略只在一个对象调用它的一对多或多对多关系时才将关系对象读取出来。这个过 程对开发者来说是透明的,而且只进行了很少的数据库操作请求,因此会得到比较明显的性能提升。这项技术的一个缺陷是延迟加载技术要求一个 Hibernate会话要在对象使用的时候一直开着。这会成为通过使用DAO模式将持久层抽象出来时的一个主要问题。为了将持久化机制完全地抽象出来,所 有的数据库逻辑,包括打开或关闭会话,都不能在应用层出现。最常见的是,一些实现了简单接口的DAO实现类将数据库逻辑完全封装起来了。一种快速但是笨拙 的解决方法是放弃DAO模式,将数据库连接逻辑加到应用层中来。这可能对一些小的应用程序有效,但是在大的系统中,这是一个严重的设计缺陷,妨碍了系统的 可扩展性。

在Web层进行延迟加载

幸运的是,Spring框架为Hibernate延迟加载与DAO模式的整合提供了一种方便的解决方法。对那些不熟悉Spring与 Hibernate集成使用的人,我不会在这里讨论过多的细节,但是我建议你去了解Hibernate与Spring集成的数据访问。以一个Web应用为 例,Spring提供了OpenSessionInViewFilter和OpenSessionInViewInterceptor。我们可以随意选择 一个类来实现相同的功能。两种方法唯一的不同就在于interceptor在Spring容器中运行并被配置在web应用的上下文中,而Filter在 Spring之前运行并被配置在web.xml中。不管用哪个,他们都在请求将当前会话与当前(数据库)线程绑定时打开Hibernate会话。一旦已绑 定到线程,这个打开了的Hibernate会话可以在DAO实现类中透明地使用。这个会话会为延迟加载数据库中值对象的视图保持打开状态。一旦这个逻辑视 图完成了,Hibernate会话会在Filter的doFilter方法或者Interceptor的postHandle方法中被关闭。下面是每个组 件的配置示例:

 

Interceptor的配置:


<beans>
<bean id="urlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="interceptors">
<list>
<ref bean="openSessionInViewInterceptor"/>
</list>
</property>
<property name="mappings">

</bean>

<bean name="openSessionInViewInterceptor"
class="org.springframework.orm.hibernate.support.OpenSessionInViewInterceptor">
<property name="sessionFactory"><ref bean="sessionFactory"/></property>
</bean>
</beans>

Filter的配置


<web-app>

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>
org.springframework.orm.hibernate.support.OpenSessionInViewFilter
</filter-class>
</filter>

<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>*. spring </url-pattern>
</filter-mapping>

</web-app>


实现Hibernate的Dao接口来使用打开的会话是很容易的。事实上,如果你已经使用了Spring框架来实现你的Hibernate Dao,很可能你不需要改变任何东西。方便的HibernateTemplate公用组件使访问数据库变成小菜一碟,而DAO接口只有通过这个组件才可以 访问到数据库。下面是一个示例的DAO:


public class HibernateProductDAO extends HibernateDaoSupport implements ProductDAO {

public Product getProduct(Integer productId) {
return (Product)getHibernateTemplate().load(Product.class, productId);
}

public Integer saveProduct(Product product) {
return (Integer) getHibernateTemplate().save(product);
}

public void updateProduct(Product product) {
getHibernateTemplate().update(product);
}
}


在业务逻辑层中使用延迟加载

即使在视图外面,Spring框架也通过使用AOP 拦截器 HibernateInterceptor来使得延迟加载变得很容易实现。这个Hibernate 拦截器透明地将调用配置在Spring应用程序上下文中的业务对象中方法的请求拦截下来,在调用方法之前打开一个Hibernate会话,然后在方法执行 完之后将会话关闭。让我们来看一个简单的例子,假设我们有一个接口BussinessObject:


public     interface    BusinessObject     {
public     void    doSomethingThatInvolvesDaos();
}
类BusinessObjectImpl实现了BusinessObject接口:

public     class    BusinessObjectImpl    implements    BusinessObject     {
public     void    doSomethingThatInvolvesDaos()     {
//    lots of logic that calls
//    DAO classes Which access
//    data objects lazily 

 

通过在Spring应用程序上下文中的一些配置,我们可以让将调用BusinessObject的方法拦截下来,再令它的方法支持延迟加载。看看下 面的一个程序片段:

 

<beans>
<bean id="hibernateInterceptor" class="org.springframework.orm.hibernate.HibernateInterceptor">
<property name="sessionFactory">
<ref bean="sessionFactory"/>
</property>
</bean>
<bean id="businessObjectTarget" class="com.acompany.BusinessObjectImpl">
<property name="someDAO"><ref bean="someDAO"/></property>
</bean>
<bean id="businessObject" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target"><ref bean="businessObjectTarget"/></property>
<property name="proxyInterfaces">
<value>com.acompany.BusinessObject</value>
</property>
<property name="interceptorNames">
<list>
<value>hibernateInterceptor</value>
</list>
</property>
</bean>
</beans>

当businessObject被调用的时候,HibernateInterceptor打开一个Hibernate会话,并将调用请求传递给 BusinessObjectImpl对象。当BusinessObjectImpl执行完成后,HibernateInterceptor透明地关闭了 会话。应用层的代码不用了解任何持久层逻辑,还是实现了延迟加载。


在单元测试中测试延迟加载

最后,我们需要用J-Unit来测试我们的延迟加载程序。我们可以轻易地通过重写TestCase类中的setUp和tearDown方法来实现这 个要求。我比较喜欢用这个方便的抽象类作为我所有测试类的基类。


public abstract class MyLazyTestCase extends TestCase {

private SessionFactory sessionFactory;
private Session session;

public void setUp() throws Exception {
super.setUp();
SessionFactory sessionFactory = (SessionFactory) getBean("sessionFactory");
session = SessionFactoryUtils.getSession(sessionFactory, true);
Session s = sessionFactory.openSession();
TransactionSynchronizationManager.bindResource(sessionFactory, new SessionHolder(s));

}

protected Object getBean(String beanName) {
//Code to get objects from Spring application context
}

public void tearDown() throws Exception {
super.tearDown();
SessionHolder holder = (SessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);
Session s = holder.getSession();
s.flush();
TransactionSynchronizationManager.unbindResource(sessionFactory);
SessionFactoryUtils.closeSessionIfNecessary(s, sessionFactory);
}

posted @ 2010-06-23 23:23 Eric_jiang 阅读(374) | 评论 (0)编辑 收藏

今天闲来无事,把一些工具(online和client的)、常用网址、以及经验总结等罗列出来和大家分享下。这个标题起地大了点,肯定会有很多地 方没列到,包括类目的分法也可能考虑不周,所以还请大家积极补充指正,可以直接留言,也可以发邮件给我(sorrycc#gmail.com)。之所以加 上“大众”两字,因为以下资源对于高手来说可能早就很熟悉了。

另外想提一句,工具是死的,好不好用得看你会不会用。比如Firefox、Fiddler等,除了显而易见的功能以外,都有一些小的技巧,掌握了可 以让你事半功倍。

更新记录:

  • [20081025] 第一版

快捷导航:

另外还搞了个Firefox插件《前端开发工 具集》,把资源整合到一个菜单下,方便查询。数据放在线上(Google AppEngine),速度应该会有保证,更新也会比较方便哈。 

在线工具集

常用Firefox插件

IE下的调试工具

  • Fiddle2 —— 非常强悍的一款http流查看工具,默认支持IE,其他浏览器可以设置将{Document}\Scripts\BrowserPAC.js设为代理进行 使用。Firefox下可用上述"Fiddler 开关"进行快速切换。支持插件
  • IE Developer Toolbar —— 查看元素、禁用缓存、禁用CSS\JS、Outline元素、查看生成的源码等功能,IE8自带了一个加强版的。
  • Microsoft Script Debugger + Companion.JS —— 调试JS用,虽然报错还是有误差,但是我已经满足了。安装顺序是:Microsoft Script Debugger,Companion.JS,在"IE选项-高级"里取消禁用脚本调试
  • 多版本IE共存两种方案:
    • IE7/8 + IE Tester —— 大众型配置,可以基本满足日常需要。
    • IE6 + Internet Explorer Collection —— 在IE 6用户占绝对优势以及IE 6神奇bug满天飞的时代,我还是推荐这种方案,因为只有神奇的原装IE 6,才能抵挡运营神奇的问题。另外如果还有其他机器可供支配的话,建议再装个IE 8 + IE Tester,因为IE 8下的Developer Toolbar还是有很大改进的,调试起来会方便一些。
  • 以下三个软件相对不重要些:

参考手册

批处理工具

IDE及其他工具

Bookmarklet(右键另存)

开发者社区及权威网站

推荐订阅的博客和网站(排名不分先后)

posted @ 2010-06-23 20:23 Eric_jiang 阅读(301) | 评论 (0)编辑 收藏

Article PS02022586

800A0001 Unspecified error

Problem Description

When uploading files with AspUpload 3.0 (and higher), the following error may be thrown by the Save method:

Persits.Upload.1 (0x800A0001)
Unspecified error

Solution

In most cases it means that your upload script uses Request.Form or Request.QueryString prior to calling Upload.Save . As a result, the BinaryRead method of the Request object fails.

You must never use Request.Form in your upload script because the ENCTYPE="multipart/form-data" attribute of your form makes this collection unusable. Use Upload.Form instead. Remeber, however, that the Upload.Form collection is populated by a call to Upload.Save, therefore you can only use Upload.Form after a successful call to Upload.Save.



简单来说,就是说你使用了这个组件 就不要再使用 Request.Form or Request.QueryString 来获取参数,都要用Upload.Form来获取,不然就报错这个错
posted @ 2010-06-22 12:07 Eric_jiang 阅读(2268) | 评论 (0)编辑 收藏

function openwindow(url,name,iWidth,iHeight)
{
var url; //转向网页的地址;
var name; //网页名称,可为空;
var iWidth; //弹出窗口的宽度;
var iHeight; //弹出窗口的高度;
var iTop = (window.screen.availHeight-30-iHeight)/2; //获得窗口的垂直位置;
var iLeft = (window.screen.availWidth-10-iWidth)/2; //获得窗口的水平位置;
window.open(url,name,'height='+iHeight+',,innerHeight='+iHeight+',width='+iWidth+',innerWidth='+iWidth+',top='+iTop+',left='+iLeft+',toolbar=no,menubar=no,scrollbars=auto,resizeable=no,location=no,status=no');
}

使用时调用这个函数即可。如:

<a href="javascript:void(0);" onclick="javascript:openwindow('a.html','',400,200);">转到a</a>

缺点:与原窗口的大小,位置无关。

posted @ 2010-06-21 13:39 Eric_jiang 阅读(2151) | 评论 (1)编辑 收藏

1.Struts2的属性驱动.

Struts2的属性驱动指的是在action中JSP页面的每一个form中的name都对应在action中有一个属性与之对应。看下面代码片段:

 


<form action="register.do" name="RegisterForm" method="post">

            Username:<input type="text" name="uname"><br>
            Password:<input type="password" name="upass"><br>
            Confirm: <input type="password" name="rpass"><br>
            <input type="submit" value="Submit">

</form>

 


这是一个最基本的用户注册的表单,它有三个数据要提交: uname、upass、rpass,那么对应的Action也要有三个属性(其实是三个属性的setter),看register.do实际的Action定义类:

 


package org.abu.csdn.action.user;

import com.opensymphony.xwork2.ActionSupport;

/**
 * Struts2属性驱动演示用的Action
 * @author 阿布
 *
 */
public class RegisterAction extends ActionSupport {

    private String uname;
    private String upass;
    private String rpass;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUpass() {
        return upass;
    }

    public void setUpass(String upass) {
        this.upass = upass;
    }

    public String getRpass() {
        return rpass;
    }

    public void setRpass(String rpass) {
        this.rpass = rpass;
    }
   
    @Override
    public String execute() throws Exception {       
        return ActionSupport.SUCCESS;
    }

}

 

 

你会看到RegisterAction中的三个属性和RegisterForm表单中的name属性名字一模一样,没错,这就是Struts2的属性驱动,当表单提交到RegisterAction后,Struts2将会自动将根据表单的name属性调用Action中相应的属性setter,去自动赋值。

 


2.Struts2的模型驱动

Struts2的模型驱动其实和Struts1.x中的ActionForm有点类似,在Struts1.x中每一个Action都必须有一个ActionForm与之对应,而Struts2.0中,每一个Action同样需要提供一个POJO对象,用来封装表单属性,看代码:

 


<form action="register.do" name="RegisterForm" method="post">

            Username:<input type="text" name="uname"><br>
            Password:<input type="password" name="upass"><br>
            Confirm: <input type="password" name="rpass"><br>
            <input type="submit" value="Submit">

</form>

 


这段表单的代码和上面的一模一样,就不赘述了。接下来看POJO的代码,其实就是普通的Java Bean:

 


package org.abu.csdn.action.user;

import com.opensymphony.xwork2.ActionSupport;

/**
 * Struts2属性驱动演示用的Java Bean
 * @author 阿布
 *
 */
public class User {

    private String uname;
    private String upass;
    private String rpass;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUpass() {
        return upass;
    }

    public void setUpass(String upass) {
        this.upass = upass;
    }

    public String getRpass() {
        return rpass;
    }

    public void setRpass(String rpass) {
        this.rpass = rpass;
    }
  
}

 


对不起,也是和属性驱动中的例子一样,很简单,因为演示的都是同一个例子,只是方法不同而已,但是接下来就不一样了,看RegisterAction代码:

 


package org.abu.csdn.action.user;

import org.abu.csdn.dto.User;

import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

/**
 * Struts2模型驱动演示用的Action
 * 
 * @author 阿布
 *
 */
public class RegisterAction extends ActionSupport implements ModelDriven<User> {

    private User user;
   
    public User getUser() {
        return user;
    }

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

    @Override
    public String execute() throws Exception {       
        return ActionSupport.SUCCESS;
    }

    // 模型驱动必须实现的方法,也是ModelDriven接口中唯一的方法
    public User getModel() {
       
        return user;
    }

}

 

 

看到没有,和属性驱动的Action有很大的区别,下面一一列举:

(1)模型驱动的Action必须实现ModelDriven接口,而且要提供相应的泛型,这里当然就是具体使用的Java Bean了。

(2)实现ModelDriven的getModel方法,其实就是简单的返回泛型的一个对象。

(3)在Action提供一个泛型的私有对象,这里就是定义一个User的user对象,并提供相应的getter与setter。

好了,上面的三件事做完之后,Action就会去自动调用User的setter将表单中的name属性的值赋给User中的属性。而Action的后续处理的Jsp页面后者是Servlet就可以使用user对象了。

 

 

 

3.到底是用属性驱动和是模型驱动呢?

 

 

这个问题困扰了很多Struts2的初学者,我这里提供一些建议:

(1)请你统一整个系统中的Action使用的驱动模型,即要么都是用属性驱动,要么都是用模型驱动。

(2)如果你的DB中的持久层的对象与表单中的属性都是一一对应的话,那么就使用模型驱动吧,毕竟看起来代码要整洁得多。

(3)如果表单的属性不是一一对应的话,那么就应该使用属性驱动,否则,你的系统就必须提供两个Bean,一个对应表单提交的数据,另一个用与持久层。

 


看上面的例子,其实密码确认rpass是不需要放到DB中去的,而仅仅是用于校验密码的,不是吗?那么如果使用模型驱动的话,就存在这个问题了,而使用属性驱动的话又有些繁琐,现在我们就来调整一个看我的解决方法:

 


4.完整的例子

(1)表单提交的JSP页面index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<%
    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>CSDN首页</title>
    </head>
    <body>
        <s:a href="userManager/userRegister.jsp">用户注册</s:a>
       
        <form action="register.do" name="SampleForm" method="post">
            Username:<input type="text" name="uname"><br>
            Password:<input type="password" name="upass"><br>
            Confirm: <input type="password" name="rpass"><br>
            <input type="submit" value="Submit">
        </form>
    </body>
</html>

 


(2)User的定义

 


package org.abu.csdn.action.user;

import com.opensymphony.xwork2.ActionSupport;

/**
 * Struts2属性驱动演示用的Java Bean
 * @author 阿布
 *
 */
public class User {

    private String uname;
    private String upass; 

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUpass() {
        return upass;
    }

    public void setUpass(String upass) {
        this.upass = upass;
    }  
  
}

 


(3)RegisterAction的定义

 


package org.abu.csdn.action.user;

import com.opensymphony.xwork2.ActionSupport;

/**
 * Struts2属性驱动演示用的Action
 * @author 阿布
 *
 */
public class RegisterAction extends ActionSupport {

 

 

    // 用来给spring注入,及属性拷贝


    private User user;

 

 

    private String uname;
    private String upass;
    private String rpass;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public String getUpass() {
        return upass;
    }

    public void setUpass(String upass) {
        this.upass = upass;
    }

    public String getRpass() {
        return rpass;
    }

    public void setRpass(String rpass) {
        this.rpass = rpass;
    }
   
    @Override
    public String execute() throws Exception {

        // 调用方法将属性copy到user中去,便于后续的service方法


        copyAttribute();

        // TODO:编写自己的user业务代码
        return ActionSupport.SUCCESS;
    }

 


    /**
     * 注意这是一个action全局的校验
     */
    @Override
    public void validate() {
        // 进行密码的校验
        if (!(upass.trim()).equals((rpass.trim()))) {
            // 注意这里addFieldError的fieldName参数必须用引号引起来,
            // 不能这样使用addFieldError(rpass,"XXXXXX"),而必须是addFieldError("rpass","XXXXX")
            this.addFieldError("rpass", this
                    .getText("csdn.action.user.register.validate.verify"));
        }
    }

 

 

 


    /**
     * 将表单属性中需要持久化的属性拷贝到user中去
     * @author 阿布
     *
    */
    private void copyAttributes () {

            user.setUname(uname);

            user.setUpass(upass);


    }


}

 

 

 

(4)Struts.xml配置

<?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>
    <package name="root" extends="struts-default" namespace="/userManager">
        <action name="userRegister" class="org.abu.csdn.action.user.RegisterAction">
            <result name="success">/index.jsp</result>
            <result name="input">/userManager/userRegister.jsp</result>
        </action>               
    </package>
</struts>

 

 

 

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/csuliky/archive/2009/05/30/4226917.aspx

posted @ 2010-06-17 21:05 Eric_jiang 阅读(9193) | 评论 (1)编辑 收藏

对Tomcat部署web应用的方式总结,常见的有以下四种:
 

1,使用控制台部署

     访问Http://localhost:8080,并通过Tomcat Manager登录,进入部署界面即可。

2,利用Tomcat自动部署

     将应用程序复制到Tomcat的 webapps路径下,Tomcat启动时将自动加载。

3,修改Server.xml文件部署

     用UE或EditPlus打开Tomcat位于conf/server.xml的配置文件,找到以下内容:

Xml代码
<Host name="localhost" debug="0" appBase="webapps"  
      unpackWARs="true" autoDeploy="true"  
      xmlValidation="false" xmlNamespaceAware="false">  
    .....   
  
</Host>  
 .....
   在Host之间添加如下内容:

来源:(http://blog.sina.com.cn/s/blog_658fbfbb0100i3sa.html) - tomcat自动部署_eric_新浪博客
Xml代码
<Context path="/Mywebapps" reloadable="true" docBase="d:\Mywebapps" workDir="d:\Mywebapps\emp"/>  

path:表示访问的路径;如上述例子中,访问该应用程序为:http://localhost:8080/Mywebapps

reloadable:表示可以在运行时在classes与lib文件夹下自动加载类包

docbase:表示应用程序的地址,注意斜杠的方向“\”

workdir:表示缓存文件的放置地址

 

4,增加自定义web部署文件(推荐使用,不需要重启Tomcat)

    在Tomcat安装目录conf\Catalina\localhost下,里面有Tomcat自带的三个应用,随意复制其中的一个XML文件,然后修改 docbase指向你自己的应用程序,并把path改名,各参数参见上第三种方法。或者你也可以自己新建一个XML文件(注意此文件名将作为 Context中的path,不管文件里的path怎么设置也无效),将以下内容复制过去,修改相应路径即可。

Xml代码
<Context path="/test" docBase="F:/J2EE/yazd_war_3_0"  
        debug="0" privileged="true" reloadable="true" >  
</Context>  

 

      部署完毕后,通过http://localhost:8080/你的path名 就可以访问。
 

posted @ 2010-06-16 14:43 Eric_jiang 阅读(3742) | 评论 (0)编辑 收藏

<host appBase="d:/aaa">
<Context path="/smswap" reloadable="true" docBase="D:\workspace\smswap\WebRoot"></Context>
</host>

我们先看appBase,这个目录表示:
1 这个目录下面的子目录将自动被部署为应用。
2 这个目录下面的.war文件将被自动解压缩并部署为应用

而docBase只是指向了你某个应用的目录,这个可以和appBase没有任何关系。

总结:
如果你想自己指定路径,那么应该在docBase里面
如果你想简单,那么直接把他们复制到appBase下面就行了

如果你把他们弄重复了,也就是2个指向了一个目录,看上去也能运行,但你的应用下面的每个子目录,其实是被部署为单独的应用的。
比如你的应用为

myApp, 放在了
d:\project\myApp
里面有2个子目录
d:\project\myApp\images
d:\project\myApp\js

你可以通过
1 设置 appBase 指向 d:\project 来让系统自动部署
2 你可以手工指定docBase到 d:\project\myApp
3 如果你指定了 appBase到 d:\project\myApp 那么
d:\project\myApp\images这个将不再是普通的子目录,而是一个单独的虚拟目录,或者叫应用了。因为其被自动部署
d:\project\myApp\js 也一样的后果
posted @ 2010-06-16 14:41 Eric_jiang 阅读(26452) | 评论 (1)编辑 收藏

    cookie虽然是由一个网页所创建,但并不只是创建cookie的网页才能读 取该cookie。在默认情况下,与创建cookie的网页在同一目录或子目录下的所有网页都可以读取该cookie。但如果在这个目录下还有子目录,要 使在子目录中也可以访问,则需要使用path参数设置cookie,语法如下:
document.cookie="name=value; path=cookieDir";
   如果要使cookie在整个网站下可用,可以将cookieDir指定为根目录,示例如下:
document.cookie="userId=320; path=/";
   上面所说都指的是在同一个目录中的访问,可是要想在不同虚拟目录中访问则要另外想办法来解决这个问题。但是path不能解决在不同域中访问cookie的 问题。在默认情况下,只有和设置cookie的网页在同一个Web服务器的网页才能访问该网页创建的cookie。但可以通过domain参数来实现对其 的控制,其语法格式如下:
document.cookie="name=value; domain=cookieDomain";

具体代码如下,直接运行即可:

设置路径:

<html>
<head>
    <title>设置cookie的路径</title>
<script language="javascript" type="text/javascript">
   <!--

    var now=new Date();
   now.setDate(now.getDate()+1);
   var cookies="userName="+escape("哈哈")+";expires="+now.toString()+";path=/";
   document.cookie=cookies;
   document.write("cookie文件中的内容为:<br>",unescape(document.cookie));
   -->
</script>

</head>
<body></body>

</html>

设置域:

<html>
<head>
    <title>设置cookie的路径</title>
<script language="javascript" type="text/javascript">
   <!--

   

   var now=new Date();
   now.setDate(now.getDate()+1);
   var cookies="userName="+escape("哈哈")+";expires="+now.toString()+";path=/; domain=.baidu.com";
   document.cookie=cookies;
   document.write("cookie文件中的内容为:<br>",unescape(document.cookie));
   -->
</script>

</head>
<body></body>

</html>

posted @ 2010-06-13 15:02 Eric_jiang 阅读(10186) | 评论 (1)编辑 收藏

1、什么是泛域名解析? 
   
泛域名解析是指将*.域名解析到同一IP。 
在域名前添加任何子域名,均可访问到所指向的WEB地址。也就是客户的域名a.com之下所设的*.a.com全部解析到同一个IP地址上去。 
比如客户设b.a.com就会自已自动解析到与a.com同一个IP地址上去。 
   
2、泛域名解析域名域名解析的区别? 
   
泛域名解析是:*.域名解析到同一IP。 
域名解析是:子域名.域名解析到同一IP。 
注意:只有客户的空间是独立IP的时候泛域名才有意义。而域名解析则没有此要求。 

   
3、怎样设置域名泛解析? 
   
您可按以下的步骤办理: 

(1)用您的用户名和密码登陆本公司站点。 
(2)域名管理--MYDNS功能--主机记录列表--在域名处输入*,在类型处选择A,顺序处不必填写保持默认值,在指向处填写服务器的ip地址,然后点击“增加新纪录”即可。
(3)如果您需要解析2级域名的泛解析比如xxx.05.abc.com,那么在上面的域名处输入*.05即可。 
(4)等半个小时到1个小时您的解析就可生效(新注册的域名24小时内生效)。 
注:请参考MYDNS功能页面内的使用帮助。 

4、相关记录说明: 
增加IP:对应IP里只能填写IP,不能填写如:http://以及:881等字符。 
修改域名DNS:该记录轻易不要设置,如果您确实懂,您可以添加新的NS记录。
posted @ 2010-06-13 10:24 Eric_jiang 阅读(345) | 评论 (0)编辑 收藏

仅列出标题
共57页: First 上一页 48 49 50 51 52 53 54 55 56 下一页 Last