转载 Seasar2框架功能参考
此内容转载自大唐云动力产品开发知识库
http://oa.icloudpower.com/seasar2/live/SAStruts.html
Seasar2
Seasar2的核心特色,即Super Agile Struts(超级敏捷开发框架,此后简称SAStruts),Seasar2实际上就是能够将传统基于Struts的系统开发过程大幅敏捷化的(Super Agile)的技术开发框架。
开发环境:JDK1.6,Eclipse(Version: 3.5以上)和Tomcat6.0
示例应用1-index
让我们来看看工程目录webapp下保存的文件,是不是有缺省显示的index.jsp(index.html)文件
在Seasar2框架中,当浏览器访问Web应用的根目录时,如果存在 RootPackage.action.IndexAction 的类,系统将自动定位到此Action。
IndexAction.java源代码:
package tutorial.action;
import org.seasar.struts.annotation.Execute;
public class IndexAction {
@Execute(validator = false)
public String index() {
return "index.jsp";
}
}
在这个action中,带有@Execute注解的方法,将被系统调用。一个action中可以定义复数个带@Execute注解的执行方法。
在本例中,action中只定义了有一个缺省的index()方法。它将被无条件调用。
方法的返回值,即为action需要跳转的页面,上述例子执行后,页面将跳转到index.jsp。
打开配置文件web.xml,其中VIEW_PREFIX定义的值为/WEB-INF/view,所以跳转的页面就是/WEB-INF/view/index.jsp。
好了。在第一个示例的说明结束之前,我们在顺便看一下webapp/WEB-INF/struts- config.xml这个配置文件。
你是否发现,这个配置文件中根本就没有有关Action及ActionForm的定义。
Seasar2是通过对url 来分析,根据一定的命名规则,准确定位到对应的Action类并执行调用。从而完全省略了对struts-config.xml文件的修改和维护。
同样,细心的你是否发现,工程里找不到webapp/WEB-INF/validation.xml文件。
Seasar2开发框架中,通过在ActionForm类中增加注解的方式,替代了传统Status通过配置文件(validation.xml)定义输 入验证的套路。
示例应用2-加法运算
AddAction.java 源代码:package tutorial.action;
import org.seasar.struts.annotation.Execute;
import org.seasar.struts.annotation.IntegerType;
import org.seasar.struts.annotation.Required;
public class AddAction {
@Required
@IntegerType
public String arg1;
@Required
@IntegerType
public String arg2;
public Integer result;
@Execute(validator = false)
public String index() {
return "index.jsp";
}
@Execute(input = "index.jsp")
public String submit() {
result = Integer.valueOf(arg1) + Integer.valueOf(arg2);
return "index.jsp";
}
}
Seasar2中定义的action类,就是一个最普通的POJO类(没有继承任何Class的简单类文 件)。
来自页面的各种请求都集中在这个类中处理。每一个请求对应一个执行函数。函数定义时,需要在前面附加@Execute注解。而函数的返回值,就是请求处理结束后,将要跳转到的页面。
下述2个url请求,都对应着Action中的同一个执行函数 :AddAction#index()
http://localhost:8080/seasar2-tutorial/add/index
http://localhost:8080/seasar2-tutorial/add/ *url中没有指明执行函数时,Seasar2将默认调用缺省的index()函数。
有关Form中的submit按钮:
<input type="submit" name="submit" value="计算"/>
Seasar2自动匹配提交按钮的name属性,所以,AddAction#submit()函数将负责处理此提交请求。
Form提交时,一般都会涉及对输入数据的验证。Seasar2是通过在输入变量上标记注解的方式来实现验证。
在@Execute中,常用的属性是validator和input。
valiator=ture时,当系统验证输入数据不合法时,页面将跳转到input属性所指定的页面。
/add/index.jsp 源代码
<html>
<head>
<title>Add</title>
</head>
<body>
<html:errors/>
<s:form>
<html:text property="arg1"/> + <html:text property="arg2"/>
= ${f:h(result)}<br />
<input type="submit" name="submit" value="计算"/>
</s:form>
</body>
</html>
对于一般JSP页面经常使用到的taglib,可以在webapp/WEB-INF/view/common/common.jsp做定义说明。
系统对输入数据验证发现错误时,需要提示验证信息,html:errors 标签显示这些信息。
定义JSP页面的Form,请使用s:form标签,标签的action属性,会由框架自动生成。一般情况下无需特别定义。
Form中的输入项目,如文本框,下拉框等,通用 html:text 等标准html标签库。 property属性即对应ActionForm类或Action类中定义的属性名称。
Form提交时,因submit的标签将name属性设置为 "submit", 所以,AddAction类中需要有对应的submit()函数,处理此按钮的处理请求。
上例中,我们对输入的2个参数作了输入验证。分别是必录项验证和整数验证。请看arg1和arg2定义上方的注解。
当验证发现输入不合法是,页面将跳转到input属性定义的index.jsp页面。验证输入合法时,submit()函数将被调用执行。
submit()函数的返回值是index.jsp。所以页面提交后,页面会跳转到index.jsp。
action类中,定义有result。jsp页面可以使用${f:h(result)}显示ActionForm或者action类中的属性值。
f:h标签,可以将变量中的特殊html字符做转换。保证正确的显示结果。
示例应用3-文件上传
UploadAction.java 源代码package tutorial.action;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.fileupload.FileUploadBase.SizeLimitExceededException;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionMessages;
import org.apache.struts.upload.FormFile;
import org.seasar.framework.container.annotation.tiger.Binding;
import org.seasar.framework.container.annotation.tiger.BindingType;
import org.seasar.framework.exception.IORuntimeException;
import org.seasar.struts.annotation.Execute;
import org.seasar.struts.annotation.Required;
import org.seasar.struts.upload.S2MultipartRequestHandler;
import org.seasar.struts.util.ActionMessagesUtil;
public class UploadAction {
@Required
@Binding(bindingType = BindingType.NONE)
public FormFile formFile;
@Binding(bindingType = BindingType.NONE)
public FormFile[] formFiles;
public HttpServletRequest request;
public ServletContext application;
@Execute(validator = false)
public String index() {
SizeLimitExceededException e = (SizeLimitExceededException) request
.getAttribute(S2MultipartRequestHandler.SIZE_EXCEPTION_KEY);
if (e != null) {
ActionMessages errors = new ActionMessages();
errors.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
"errors.upload.size",
new Object[] { e.getPermittedSize(), e.getActualSize() }));
ActionMessagesUtil.addErrors(request, errors);
}
return "index.jsp";
}
@Execute(input = "index.jsp")
public String upload() {
ActionMessages messages = new ActionMessages();
upload(formFile, messages);
for (FormFile file : formFiles) {
upload(file, messages);
}
ActionMessagesUtil.addMessages(request, messages);
return "index.jsp";
}
protected void upload(FormFile file, ActionMessages messages) {
if (file.getFileSize() == 0) {
return;
}
String path = application.getRealPath("/WEB-INF/work/"
+ file.getFileName());
try {
OutputStream out = new BufferedOutputStream(new FileOutputStream(
path));
try {
out.write(file.getFileData(), 0, file.getFileSize());
} finally {
out.close();
}
} catch (IOException e) {
throw new IORuntimeException(e);
}
messages.add(ActionMessages.GLOBAL_MESSAGE, new ActionMessage(
"messages.upload.complete",
new Object[] { path }));
}
}
Seasar2框架提供有方便的文件上传类,开发带有文件上传的应用,开发者只需在Action或ActionForm中,定义FormFile类型的变量就可以了。
我们可以将存放UpladFile的变量定义为数组,如FormFile[],便可以从提交的Form中获取多个上传文件对象。
当FormFile定义为数组时,无法通过加注验证注解方式验证上传文件。此时如需要验证上传是否成功,需要通过FormFile#getFileSize()是否为0来判断。
我们可以在配置文件里限制上传文件的大小。(struts-config.xml中controller节点的maxFileSize属性值),如果接受到的文件超过了配置文件设定的上限。框架将抛出SizeLimitExceededException异常。
上述示例中,有异常发生时,处理将跳转到index函数,所以在index函数中,通过判断否存在SizeLimitExceededException来确定上传文件大小是否超过上限。
/upload/index.jsp源代码
<html>
<head>
<title>Upload</title>
</head>
<body>
<html:errors/>
<html:messages id="m" message="true">
${f:h(m)}<br />
</html:messages>
<s:form action="/upload" enctype="multipart/form-data">
<input type="file" name="formFile" /><br />
<c:forEach varStatus="s" begin="0" end="1">
<input type="file" name="formFiles[${s.index}]" /><br />
</c:forEach>
<input type="submit" name="upload" value="上传"/>
</s:form>
</body>
</html>
带有文件上传的页面,注意form的enctype属性要设置为"multipart/form- data"。上 传标签(<input type="file" ... />)的name属性要与Action或者ActionForm内的属性变量名称相。
页面的FormFile如果是要处理数组形式的文件上传,上传标签的name属性値需要写成 属性名[数组下标] 的形式。
功能参考
本章介绍Seasar2框架的主要功能及配置规则。完成本章的学习,在回过头结合上一章节的示例后,你也可以轻松自如的开发构建属于自己的应用工程了。
Project构成
Seasar2构建的工程的src目录中,需要有一个RootPackage包,RootPackage包的名字可以自定义,以示例工程seasar2-tutorial为例,工程中指定的RootPackage包名称为tutorial。
在包名确定后,需要确定配置文件convention.dicon中的配置是否与这个包名一致。
convention.dicon 内容
<components>
<component
class="org.seasar.framework.convention.impl.NamingConventionImpl">
<initMethod name="addRootPackageName">
<arg>"tutorial"</arg>
</initMethod>
</component>
<component
class="org.seasar.framework.convention.impl.PersistenceConventionImpl"/>
</components>
在RootPackage下一般会有下面几个典型的java包
Action
系统中所有Action处理,都在RootPackage.Action下做定义,比如
与http://hostname/projectname/xxx/ 这样的URL相对应的Action类,就是XxxAction.java (注意大小写)
ActionForm
Action中对应的ActionForm,都在RootPackage.Form下做定义,比如,XxxAction中对应的ActionForm,其名称就对应为XxxForm。(注意大小写)
ActionForm的作用就是接受来自页面提交的输入/输出参数。(虽然这些参数都可以在action中定义,但从维护,可读的角度来要求,我们规定,对于Action处理中需要处理的页面输入输出参数,都要在ActionForm类中相应的变量定义)
Entity
系统中所有Entity类,都在RootPackage.Entity下做定义。Entity是用户储存数据库持久层的数据实体类。对于Entity的命名没有特别的规定。一般情况下可沿用数据库表的名称。
Service
对Entity操作的类,这里我们称为Service。系统中所有Entity类,都在 RootPackage.Service下做定义。
Serivce的类名称形如 XxxService, 因为一个Service通常与一个Entity对应, 所以Xxx部分原则上使用与之对应的Entity名称。(*关于数据持久层的说明,请参考S2JDBC进阶章节)
Util
工程项目中会经常调用到的自定义的工具类,可都存放在在RootPackage.Util下,没有特别的命名要求。
应用程序体系结构
Seasar2框架从根本上来说,也是基于MVC(Model View Controller)体系结构衍生而成的, Model对应Entity、View对应JSP、Controller对应Action。
一个Action中,可以包含多个执行方法(函数)。通常,一个UseCase映射一个Action。
在B/S系统中也可以认为,业务由多个页面构成,页面是构成UseCase的基本单位。而数据如何在页面中显示的逻辑,则在Action中做编码定义。
业务逻辑处理一般定义在Service中。也有一种设计观点认为。通过Dao(Data Access Object),可以进一步把数据访问从业务逻辑中抽出,以应对开发过程中发生的数据访问层框架的变更。
但这种情况基本上不会发生,故在Seasar2框 架中,数据访问处理可以直接写在业务逻辑中。
Action
服务器端用以响应处理浏览器请求(Request)的类,这里称之为Action。 在Struts里,URL和Action的对应关系,需要在struts-config.xml中定义,在Seasar2框架中,这个对应关系通过下述约 定的命名规则由框架自动确定,不需要再对struts-config.xml做任何编辑修改。
举例来说 http://localhost:8080/seasar2-tutorial/login/
首先,seasar2-tutorial 是应用名称。
再往后,Seasar2将根据下述规则,将URL转换定位到对应的Action。
* Web应用名之后的是请求的路径,/login/ , 将路径最后的/去掉,并加上Action后缀, 变成 loginAction
* 将首字母转换为大写字母 loginAction --〉LoginAction
* 前置 RootPackage.action.
* 通过上面3步的转换,Seasar2最终将、/login/ 这个URL映射到 tutorial.action.LoginAction 这个类。
如果请求URL中没有ActionPATH,框架会查找是否存在有 RootPackage.action.IndexAction这个类,并加载执行。
http://localhost:8080/seasra2- tutorial/ 对应的Action就是 tutorial.action.IndexAction。
补充,如果想让系统缺省调用IndexAction,要注意Web的根目录下不要存放有 index.jsp。其执行的优先度高于IndexAction。
ActionPath可以进一步分割子集,如/aaa/bbb/这样的请求url的ActionPath,对应执行RootPackage.action.aaa.BbbAction类。
Seasar2中的Action类,是POJO(最普通的Java类)。 不需要继承Strtus的Action。
在Action中通常会要使用到ActionForm,引用ActionForm时,请附加@ActionFormと@Resource注解,引用的ActionForm的实体变量名,固定定义为ActionForm类名的(首字母需转为小写)
ActionForm 引用示例
@ActionForm
@Resource
protected AddForm addForm;
向JSP页面输出的值以及而来自JSP页面提交的数据,既可以在Action类中作为属性定义,也可以将其定义在ActionForm中。但原则上请定义都在ActionForm中。
当有些信息(如Login用户名)需要在Session中管理保存时,将其放入RootPackage.dto.XxxDto。并通过注解@Component声明他将在Session中管理。
@Component(instance = InstanceType.SESSION)
public class UserDto implements Serializable {
private static final long serialVersionUID = 1L;
public String userName;
...
}
在Action中使用上述UserDto时、需要做如下变量定义, 前置注解@Resource,变量名为类名称,首字母替换为小写。
@Resource
protected UserDto userDto;
相似的,我们编写的业务逻辑代码,都汇集到RootPackage.service包下,命名为XxxService。
public class XxxService {
...
}
在Action中,需要调用Service时, 按相同的命名规范定义实体,如下:
@Resource
protected XxxService xxxService;
同理,对于HttpServletRequest、HttpServletResponse等Servlet API相关的对象,也可通过前置@Resource注解的方式建立引用。
示例代码:
public class MyAction {
@Resourceprotected HttpServletRequest request;
@Resourceprotected HttpServletResponse response;
@Resource
protected HttpSession session;
@Resource
protected ServletContext application;
...
}
执行方法(函数)
Action类中的,对应于Request请求的处理函数,称为执行方法(函数),
方法名(函数名)任意,前置@Execute注解。方法的返回值是String,方法不带任何参数。
@Execute
public String xxx() {
...
return ...;
}
执行方法的返回值,就是处理完成后页面跳转的地址,
如返回值不是以/开头的,系统将以Action所在Path作为相对路径的起始点。
例如,/add/的Action的返回值为index.jsp时,跳转的页面即为/add/index.jsp。
在web.xml中有一个VIEW_PREFIX参数,用以确定该jsp文件在工程中的位置。
在seasar2-tutorial工程里,VIEW_PREFIX的值为/WEB-INF/view,所以跳转页面所在的位置就在/WEB-INF/view/add/index.jsp。
如返回值是以/开头的,系统则认为是Web应用的根地址为相对路径的起始点。
例如,返回值是/select/时,跳转的页面就是 http://localhost:8080/seasar2-tutorial/select/ 。
页面的跳转方法,缺省为FORWARD,当需要使用重定向方式是,需要在返回路径的后面追加redirect=true的参数。形如,
...
return "xxx.jsp?redirect=true";
...
return "xxx.jsp?key=value&redirect=true";
跨域跳转
...
return "https://hostname/appname/path/?redirect=true";
也有些情况,如文件下载等请求处理,只通过Response直接输出而没有跳转时,执行方法的返回值设为null。
一个Action类中,可以定义多个执行方法。具体到哪一个方法被调用,则是由请求URL,JSP页面提交按钮的Name属性值来确定。
如下的例子、AddAction#index()将被调用执行。
http://localhost:8080/sa-struts-tutorial/add/index
http://localhost:8080/sa-struts-tutorial/add/ (url中没有执行方法名时,index()方法将被缺省调用)
故上述2个URL等效。
再看一个页面提交的例子
JSP页面的按钮定义为
<input type="submit" name="confirm" value="确认提交"/>
此提交按钮标签的name属性值是comfirm。Action类中的conFirm()方法负责处理通过此按钮提交后的一系列工作。
如希望窗体提交前做必要的输入数据验证,Seaser2提供了比较简易的方法。 将@Execute注解的validator参数置为true。缺省为true。
当验证出错后,页面将跳转到input参数指定的页面。
@Execute(validator = true, input = "edit.jsp")
ActionForm
ActionForm,主要用于管理Request中的输入输出参数,是一个普通的POJO。
输入输出参数的名字对应ActionForm内定义各属性变量。
Seasar2中,Action的生存期缺省为Request周期,如要提升为Session生存周期,需要增加一行注解的描述。
@Component(instance = InstanceType.SESSION)
public class XxxForm implements Serializable {
private static final long serialVersionUID = 1L;...
}
需要注意的一点,需要归入Session生存周期管理的组件,必须implements Serializable。
进一步,使用对输入对象做数据验证,也是在ActionForm中通过对属性变量前置注解来实现。
@Required
public String arg1;
* 对arg1做必须输入的验证
Ajax
Seasar2支持Ajax调用。最常见的是通过jquery调用。
Ajax调用时,Action的执行方法内,直接使用ResponseUtil.write("字符串"),输出字符文本。也没有页面迁移,所以方法的返回值是null。
@Execute(validator = false)
public String hello() {
ResponseUtil.write("Hello Ajax");
return null;
}
在jsp文件中,使用到jquery,需要包含jquery库。
<script src="${f:url('/js/jquery.js')}"></script>
...
<span id="message"></span><br />
<input type="button" value="hello"
onclick="$('#message').load('hello');"/>
上例中,在jsp页面中,通过$('TAGid').load('执行方法名');的写法,可以将Ajax调用的输出结果赋回页面的指定元素(TAGID)。
有关Seasar2框架的基础知识就是这些。掌握的这些基础知识,你已经可以自己开发一些简单的Web应用了!细心的读者可能发现,这里还没有详细设计到对数据库,事务的介绍。这将在下一篇,Seasea2进阶章节做进一步介绍。
Seasar2 使用进阶 (数据库访问及有关配置文件)
本章节结合示例代码重点介绍如何利用Seaser2附带的S2JDBC持久层框架,快速实现对数据库数据的增删查改和事务控制。
前面的章节提到过,对数据库操作的业务逻辑,可以放在Service层中实现。
Seasar2框架中缺省包含有S2JDBC持久层框架,实现对各类数据库的通用支持,与数据库连接有关的配置信息,都通过配置文件jdbc.dicon统一管理。
S2JDBC支持多种市面常见的数据库,这些信息定义在配置文件s2jdbc.dicon中,根据项目实际情况进行修改。
在实际代码中,我们通过JdbcManager实例与持久层框架S2JDBC交互。
Service或者Action中,引用JdbcManager的方法如下:
@Resource
protected JdbcManager jdbcManager;
自动事务
在Action或Service中,如需要打开或关闭例外,异常发生后的事务自动回滚,请修改配置文件cutomizer.dicon。
<component name="actionCustomizer"
class="org.seasar.framework.container.customizer.CustomizerChain">
<initMethod name="addCustomizer">
<arg>
<component
class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/>
</arg>
</initMethod>
...
</component>
<component name="serviceCustomizer"
class="org.seasar.framework.container.customizer.CustomizerChain">
<initMethod name="addCustomizer">
<arg>
<component
class="org.seasar.framework.container.customizer.TxAttributeCustomizer"/>
</arg>
</initMethod>
...
S2JDBC示例汇编
下面的例子,演示了如何通过jdbcmanager,完成对数据库表的CRUD操作。
-
SELECT
/*多条结果*/
List<Employee> results = jdbcManager.from(Employee.class)
.join("department")
.where("id in (? , ?)", 11, 22)
.orderBy("name")
.getResultList();/*单条结果*/
Employee result =
jdbcManager
.from(Employee.class)
.where("id = ?", 1)
.getSingleResult();
System.out.println(result.name);* Employee是一个Entity,其属性一般都对应于数据库表的定义,其中没有业务逻辑,可以通过工具自动生成,提高编码效率。
/**
* Employee 实体类
*
*/
@Entity
public class Employee {
/** id字段属性 */
@Id
@Column
public Integer id;
/** name 字段 属性 */
@Column
public String name;
/** jobType 字段 属性 */
@Column
public Integer jobType;
/** salary 字段 属性 */
@Column
public Integer salary;
/** departmentId 字段 属性 */
@Column(nullable = true, unique = false)
public Integer departmentId;
/** addressId 字段 属性 */
@Column(nullable = true, unique = true)
public Integer addressId;
}
- Select (结果分页)
List < Employee > results =
jdbcManager
. from ( Employee . class )
. orderBy ( "id" )
. limit ( 5 )
. offset ( 4 )
. getResultList ();
for ( Employee e : results ) {
System . out . println ( e . id );
} -
Insert
public void testInsertTx () throws Exception {
Employee emp = new Employee ();
emp . name = "test" ;
emp . jobType = JobType . ANALYST ;
emp . salary = 300 ;
jdbcManager . insert ( emp ). execute ();
} -
Update
mployee emp =
jdbcManager
. from ( Employee . class )
. where ( "id = ?" , 1 )
. getSingleResult ();
emp . name = "hoge" ;
jdbcManager . update ( emp ). execute ();
- Delete
Employee emp =
jdbcManager
.from(Employee.class)
.where("id = ?", 1)
.getSingleResult();
jdbcManager.delete(emp).execute();
emp =
jdbcManager
.from(Employee.class)
.where("id = ?", 1)
.getSingleResult();
对于单表的简单数据表操作,可以通过以上的方式完成。对于多表结合等复杂SQL的操作,JdbaManager提供另外一种直接执行SQL或SQL文件的方法。
-
代码内SQL定义
private static final String SELECT_SQL =
"select e.*, d.name as department_name"
+ " from employee e left outer join department d"
+ " on e.department_id = d.id"
+ " where d.id = ?" ;
...
List < EmployeeDto > results =
jdbcManager
. selectBySql ( EmployeeDto . class , SELECT_SQL , 1 )
. getResultList ();
for ( EmployeeDto e : results ) {
System . out . println ( e . name + " " + e . departmentName );
}
-
执行外部SQL文件定义
SelectParam param = new SelectParam ();
param . salaryMin = new BigDecimal ( 1200 );
param . salaryMax = new BigDecimal ( 1800 );
List < EmployeeDto > results =
jdbcManager
. selectBySqlFile (
EmployeeDto . class ,
"examples/sql/employee/selectAll.sql" ,
param )
. getResultList ();
看一下sql文件是如何定义的examples/sql/employee/selectAll.sql:( SQL定义文件必须保存为UTF-8编码)。
select * from employee where
salary <= /*salaryMin*/ 1000
and salary >= /*salaryMax*/ 2000
SQL中的查询参数,可以是Map,也可以是一个POJO,只要KEY或者属性名和sql文件中定义的参数名称一致即可。
SelectParam
.java:
package examples . entity . Employee ;
public class SelectAllParam {
public BigDecimal salaryMin ;
public BigDecimal salaryMax ;
}
-
复杂SQL的分页,注意,实现分页的SQL定义中,一定要有order by。
jdbcManager
.selectBySql(
EmployeeDto.class,
"select id, name from employee order by name")
.limit(100)
.offset(10)
.getResultList();
-
通过SQL实现,insert/update/delete
jdbcManager
.updateBySql(
"update employee set salary = ? where id = ?",
BigDecimal.class,
Integer.class)
.params(null, 1)
.execute();
到此,有关Seasar2快速开发框架的基本使用就介绍完了。更多的使用技巧,需要你在实际的项目中不断 积累和摸索。
多读读别人写的程序。对自己也是很好的提高。
常见问题(Question And Answer)
Question 1:Web.xml中是否可以定义自己的Servlet?
Answer:可以。Seasar框架本身支持开发者自己编写的Servlet。 但主要注意的是。当在Servlet中需要用到Seasar2提供的组件时,
请务必通过SingletonS2ContainerFactory(单例容器工厂)对象建立引用。
例:在servlet中使用jdbcmanager.
final String PATH = "s2jdbc_cloud.dicon";
SingletonS2ContainerFactory.setConfigPath(PATH);
SingletonS2ContainerFactory.init();
S2Container s2Container = SingletonS2ContainerFactory.getContainer();
jdbcmanager = (JdbcManager) s2Container.getComponent("jdbcManager_cloud");
Question 2:s2jdbc是否支持oracle的BLOB字段类型?
Answer:支持。entity类中定义的字段项加注 @Lob 注解即可
例:
@Lob
@Column(name = "IMAGEDATA")
public
byte
[]
imagedata
;

浙公网安备 33010602011771号