功能参考
SAStruts的各项功能说明。
プロジェクト構成
SAStruts在包下做成action,actionForm等包。 报名可以任意指定,比如sa-struts-tutorial工程,报名定义为tutorial。
报名需要在convention.dicon中指定。sa-struts-tutorial工程中的配置如下。
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>
Action放置在包名.action下。 比如URLhttp://host/project/xxx/对应的Action类的名称为XxxAction。
ActionForm放置在包名.form下。 比如XxxAction对应的ActionFrom的名称为XxxFor。ActionForm对Request的参数进行管理。
entity放置在包名.entity下。 实体是数据库中保存的数据。实体可以任意命名,但一般使用对应的表名。
对实体进行操作的类称为Service。Service放置在包名.service下。 一般使用XxxService这样的以Service结尾的名称。Xxx可以为任意名称,但一般使用实体名。
utility一般放在包名.util下。 类名可以自由定义。utility类一般由static方法构成。
JSP放在Action对应的目录下。 比如XxxAction使用的JSP,放在/xxx/目录下比较好。
应用架构
SAStruts是实现MVC(Model View Controller)模式的架构,Model是Entity、View是JSP,Controller是Action。
Action可以包含多个方法,通常1个用例 映射为1个Action。 一个用例可以包含多个画面,表现层关联的逻辑,在Action里定义。
业务逻辑可以定义在entity或者Service中。 数据访问逻辑也包含在业务逻辑中比较好。 业务逻辑和数据访问层框架分离,用Dao来实现数据访问。 但实际开发过程中,极少会出现中途换数据访问框架的场面,所以认为业务逻辑中包含数据访问比较好。
业务逻辑是定义在Entity还是Service里是个重要的问题。 数据访问逻辑,定义在Service里比较好。比如查询方法,因为得到实体本身的方法,不可能在实体中定义。 当然,如果定义为实体的static方法,也是能实现,但静态方法,在测试时不能被重载,所以不这样做比较好。/p>
还有,更新的方法,使用Entity也行。但是需要继承又更新方法的特定类,这不符合最近的POJO倾向。 所以数据访问逻辑,还是放在Service中比较好。
实体的导出属性,在实体中定义比较好。如果有需要进行计算的属性,需要实现对应的getter方法。 导出属性,实体属性的一种,在实体中定义是自然的。
除了数据访问和导出属性外,需要根据实际情况,在Entity和Service中处理逻辑。
我的判断基准是,怎么样能减少代码量,因为代码量少,出错的几率就小。 当然这不可能是解决所有的问题,但是也可以作为一个判断基准。
最后,特定Entity关联的常量,分别定义在对应的Entity中。
Action
对用户请求进行相应的类称为Action。Struts中,URL和Action的关系在struts-config.xml里进行定义。SAStruts根据下面的规则自动映射,不需要再配置文件中定义。
比如 http://localhost:8080/sa-struts-tutorial/login/。sa-struts-tutorial是Web应用的名称。SAStruts根据下面的规则将URL转换为Action的类名。
- Web应用名后面的路径(/login/)的最后的反斜线“/”加上Action转换为/loginAction。 没有反斜线直接加Action。
- 开始的字母大写化为/LoginAction。
- 反斜线转换成点(.LoginAction)。
- 在类名之前加上包名.action转换成报名.action.LoginAction。 包名的详细信息请参考这里。
- 最重,/login/对应的类为tutorial.action.LoginAction。
Action对应的路径不存在的情况下,如果存在Action包名.action.IndexAction,则调用对应的IndexAction。 比如输入http://localhost:8080/sa-struts-tutorial/则调用tutorial.action.IndexAction。
如果要调用IndexAction,在Web的根目录下不要放置index.jsp文件。index.jsp将被优先调用。
如果是大型的应用开发,也可以增加包的层数。比如/aaa/bbb/对应的Action为: 包名.action.aaa.BbbAction。
Action已经POJO化(普通的JAVA类),不需要像Strus一样继承Action。
Scope为请求(请求),不像Struts为singleton。ActionForm等请求或者Session管理的对象作为Property进行读取。因为是请求进行管理, 所以不用像Struts那样担心线程安全。
使用ActionForm的时候,像下面一样进行定义。加上@ActionFormと@Resource注释。@Resource是用来定义Seasar2能够读取的Annotation。 变量名是将类名的开头字母小写化转换而成。
@ActionForm @Resource protected AddForm addForm;
只有需要在JSP中输出的值,在Action里定义变量。 请求需要的变脸,请通过ActiomForm进行传输。
通过Session管理用户信息的时候, 在包名.dto下创建XxxDto,加上注释@Component注明使用Session进行管理。
Seasar2、Dto定义为public时,能够自动判别为属性。
@Component(instance = InstanceType.SESSION) public class UserDto implements Serializable { private static final long serialVersionUID = 1L; public String userName; ... }
利用创建的UserDto时,需要像以下的定义一样加上@Resource定义。(以下的代码由于声明为非public,通过JSP不能查看) 变量名为类名开头字母小写。
@Resource protected UserDto userDto;
利用Session管理Dto的时候,Dto在热部署时可能失效。 使用Tomcat时,请参照context.xml进行修改。
业务逻辑放在Service包下时,在包名.service下创建XxxService。
public class XxxService { ... }
使用XxxService,需要像以下的定义一样加上@Resource定义。 变量名为类名开头字母小写。
@Resource protected XxxService xxxService;
需要使用HttpServletRequest,HttpServletResponse等Servlet API相关对象的时候、 需要像以下的定义一样加上@Resource定义。 变量名定义如下所示。
public class MyAction { @Resource protected HttpServletRequest request; @Resource protected HttpServletResponse response; @Resource protected HttpSession session; @Resource protected ServletContext application; ... }
请求对应的处理,请参考执行方法。
执行方法
实际处理请求的Action方法。执行方法名可为任意,需加上注释@Execute,返回值 为String,不能有参数。
@Execute public String xxx() { ... return ...; }
执行方法的返回值,是需要跳转页面的路径,是Action的相对路径。
例如/add/的Action的返回值为index.jsp的时候,路径转换为/add/index.jsp。 然后加上web.xml的VIEW_PREFIX定义的路径做为前缀。sa-struts-tutorial工程,VIEW_PREFIX定义为/WEB-INF/view则将跳转到/WEB-INF/view/add/index.jsp。
如果跳转String为/结尾的时候,则跳转到对应的Action。 比如返回值为/select/的时候,则跳转到http://localhost:8080/sa-struts-tutorial/select/。
默认为forward跳转,如果需要进行Redirect跳转时,需要最末尾加上redirect=true=前后不能有空白。
... return "xxx.jsp?redirect=true";
... return "xxx.jsp?key=value&redirect=true";
如果需要跳转到别的Site,需要返回完整的URL。
... return "https://主机名/应用名/路径/?redirect=true";
如果是文件下载或者又Response来响应的时候,返回值设为null。
1个Actio可以包含多个执行方法,通过URL来选择对应的执行方法。 请求的参数的键中包含了方法名,请求的参数SAStruts.method中指定了方法名。
比如,调用AddAction#index()方法时。
http://localhost:8080/sa-struts-tutorial/add/index
没有制定方法时,则调用默认的index()方法、所有下面的URL调用的也是AddAction#index()。
http://localhost:8080/sa-struts-tutorial/add/
通过制定@Execute的urlPattern,URL跟Pattern一直的方法将被调用。 并且URL的一部分参数的值能够被接收。
内部逻辑为,RoutingFilter来过滤URL一致的Pattern。一致的时候,则调用对应的方法,Pattern的{参数名}部分,将对应的值保存进取,然后Forward给Struts。
比如下面的EmployeeAction#edit()定义。
@Execute(urlPattern = "edit/{id}") public String edit() { ... }
/employee/list.jsp页面中的超链接定义为。
<a href="edit/1">编辑</a>
RoutingFilter过滤重新组装成下面的参数返回给Struts。
/employee.do?id=1&SAStruts.method=edit
SAStruts,参数id作为Action的属性,SAStruts.method参数指定调用的方法名。
进行表单提交的时候,按钮的name属性就是要调用方法的名字。 比如,下例就是调用confirm方法。
<input type="submit" name="confirm" value="确认"/>
调用执行方法前,使用Annotation进行验证, @Execute的validator设置为true。默认为true。
validator=true的时候,如果验证结果为NG,则跳转input制定的路径。input路径的定义方法,类似于执行方法的返回值,不过可以像urlPattern一样指定({参数})。 验证的详细请参照这里。
@Execute(validator = true, input = "edit.jsp")
调用执行方法前,如果要进行调用自己定义的验证方法。@Execute的validate中定义ActionForm的验证方法名。
如果验证结果为NG,则跳转input制定的路径。 如果在validator和validate中都定义了的情况下、声明式验证优先,然后是validate定义的自定义方法。 自定义方法请参照这里。
@Execute(validate = "validate", input = "login.jsp")
roles指定调用该法观念法需要的角色。 需要指定多个角色时用逗号分隔。 如果不是定义的角色,则抛出org.seasar.struts.exception.NoRoleRuntimeException异常。NoRoleRuntimeException异常被抛出时,调转到对应的异常页面(/error/norole.jsp)、 对应的(errors.norole)消息已经被定义。
application_jp.properties
errors.norole=適切なロールがありません。
struts-config.xml
<global-exceptions> <exception path="/error/norole.jsp" key="errors.norole" type="org.seasar.struts.exception.NoRoleRuntimeException"/> </global-exceptions>
/error/norole.jsp
<html> <head> <title>Role error</title> </head> <body> <html:errors property="errors.norole"/> </body> </html>
ActionForm
ActionForm是管理请求参数的类。 对于SAStruts,ActionFrom也可以用POJO来实现。
ActionForm中,请求的参数名作为变量被定义。 为了接受参数而定义的变量,也可以存放检验的错误信息。 类型为String或者Boolean。Seasar2,ActionForm里声明为public的变量,可以被视为属性。
使用ActionForm时,请注意不能用Action的属性来接收请求的参数。
ActionForm存放在包名.form下,类名以Form结尾。
SAStruts的ActionForm默认的Scope为请求,但是可以通过下面的 声明来指定Scope为Session.如果Scope为Seesion的时候需要实现接口java.io.Serializableをimplements。
@Component(instance = InstanceType.SESSION) public class XxxForm implements Serializable { private static final long serialVersionUID = 1L; ... }
ActionForm的Scope为Session的时候,、 可以通过将Execute的removeActionForm元素的值设为true来实现,当执行方法结束时删除ActionForm。 默认值为False,不删除。
利用Session管理ActionForm的时候,ActionForm在热部署时可能失效。 使用Tomcat时,请参照context.xml进行修改。
可以如下所示对变量实现声明式的验证。 声明式的验证的详细信息请参考、这里。
@Required public String arg1;
也可以如下所示,添加自己的验证方法。 验证方法的详细请参考这里。
public ActionMessages validate() { ActionMessages errors = new ActionMessages(); ... return errors; }
CheckBox等的初始化,可以参考下面的reset方法进行。reset方法的详细请参考这里。
public void reset() { checked = false; }
声明式验证
通过使用注解(Annotation)来对ActionForm来进行验证。 验证用的注解(Annotation)请参考这里。
@Required public String userName;
验证NG的时候输出的错误信息在信息资源里进行了定义。 验证用的注解和对应错误信息的键入下所示。
Annotation | 信息键 |
---|---|
Required | errors.required |
Validwhen | 开发者自己定义 |
Minlength | errors.minlength |
Maxlength | errors.maxlength |
Minbytelength | errors.minbytelength |
Maxbytelength | errors.maxbytelength |
Mask | errors.invalid |
IntRange | errors.range |
LongRange | errors.range |
FloatRange | errors.range |
DoubleRange | errors.range |
ByteType | errors.byte |
ShortType | errors.short |
IntegerType | errors.integer |
LongType | errors.long |
FloatType | errors.float |
DoubleType | errors.double |
DateType | errors.date |
CreditCardType | errors.creditcard |
EmailType | errors.email |
UrlType | errors.url |
需要对已经定义的信息进行修改的时候,只需要修改信息键对应的值。
对于特别的属性,需要追加自定义信息的时候,信息资源里追加对应的信息, 然后再注解中使用msg元素来指定。
errors.required2={0}必须有值。
@Required(msg = @Msg(key = "errors.required2"))
信息中,{位置}中的值可以指定。位置从0开始。 注解中,可以通过参数arg0, arg1, ..., args元素来指定。
@Required(arg0 = @Arg(key = "ほげ", resource = false))
@Validwhen(test = "((validwhen1Text == null) or (*this* != null))", msg = @Msg(key = "errors.required.other"), args = @Arg(key = "validwhen1Text", resource = false, position = 1))
最开始的参数,自动设置为属性名。需要对属性进行定制的时候, 可以在信息资源中
追加labels.属性名=...的定义。
labels.userName=用户名
使用target元素可以在指定的方法调用时,进行参数验证。如果是多个方法的时候, 使用逗号进行分隔。target元素没有被定义,@Execute的validator=true则调用所有方法的时候都需要进行验证。 下例为,属性second在调用goThird方法时,验证必须有值
@Required(target = "goThird") public String second;
JSP中输出错误信息时,使用如下所示的html:errors标签。
<%@taglib prefix="html" uri="http://struts.apache.org/tags-html"%> ... <html:errors />
需要追加自定义注解验证的时候,请参照org.seasar.struts.validator.S2FieldChecks来实现验证逻辑,然后 将方法添加到validator-rules.xml。
validator-rules.xml定义validator名指定为Validator Annotation。
想要使用JavaScript进行客户端验证时,请参考指南。
使用验证方法
如果需要自己定制验证方法的时候,可以在ActionForm或者Action里追加方法。 不过推荐在有验证对象的ActionForm里进行。
验证方法,方法名任意,没有参数,返回值为ActionMessages。 返回值不为空的时候,验证结果NG。
public ActionMessages validate() { ActionMessages errors = new ActionMessages(); ... return errors; }
执行方法上,通过validate元素来指定验证方法。设定好validate的时候,如果验证失败将跳转回input指定的页面。
@Execute(validate = "validate", input = "login.jsp")
使用任意方法验证的时候,验证结果为NG的时候,抛出ActionMessagesException异常。
public void validateLogin(String userName, String password) { if (!userName.equals(password)) { throw new ActionMessagesException("errors.invalid.login"); } }
ActionMessagesException的处理,在app.dicon中定义
org.seasar.struts.interceptor.ActionMessagesThrowsInterceptor,customizer.dicon里定义的拦截器能够使用。app.dicon和customizer.dicon,在工程sa-struts-tutorial下,放置在src/main/resources目录下。
app.dicon
<component name="actionMessagesThrowsInterceptor" class="org.seasar.struts.interceptor.ActionMessagesThrowsInterceptor"/>
customizer.dicon
<component name="actionCustomizer" class="org.seasar.framework.container.customizer.CustomizerChain"> ... <initMethod name="addAspectCustomizer"> <arg>"actionMessagesThrowsInterceptor"</arg> </initMethod> ... </component>
重置方法
CheckBox(<input type="checkbox" .../>)或者多选列表(<select multiple="multiple" ...></select>),选中的值被传请求传送。 使用Session管理ActionForm的时候,需要将CheckBox或者多选列表重置。
为此可以在ActionForm中添加重置(reset)方法。 重置方法,在请求将参数传入ActionForm之前被调用。
@Component(instance = InstanceType.SESSION) public class XxxForm implements Serializable { private static final long serialVersionUID = 1L; public boolean foo; public String[] bar; ... public void reset() { foo = false; bar = new String[0]; } }
重置方法名可以在执行方法中定义。默认为reset。
@Execute(reset = "执行方法名", ...)
文件上传
文件上穿,在Action或者ActionForm中定义FormFile类型的属性,通过FormFile得到上传的文件。
如果定义为FormFile[]类型的数组,这可以上传多个文件。请参照 詳しくは指南的文件上传。
Ajax
SAStruts可以组合使用任意的Ajax库。 这里以使用jQuery为例进行说明。
在Action的执行方法中,使用ResponseUtil.write("文字列")来向Response写入返回字符串。 因为不需要进行页面跳转,返回值为null。
@Execute(validator = false) public String hello() { ResponseUtil.write("こんにちは"); return null; }
JSPでは、jQueryを使うためにヘッダでjquery.jsを取り込みます。あるタグをアクションの実行メソッドがレスポンスに書き込んだ値で置き換える場合は、$('タグのid').load('実行メソッド名');を呼び出します。
<script src="${f:url('/js/jquery.js')}"></script> ... <span id="message"></span><br /> <input type="button" value="hello" onclick="$('#message').load('hello');"/>
需要向Action传递参数的时候,在load的第二个参数中追加,如下例
public String greeting; ... @Execute(validator = false) public String hello() { ResponseUtil.write(greeting); return null; }
<input type="button" value="hello" onclick="$('#message').load('hello',{'greeting':'Hello'});"/>
也可以通过URL传递参数。
public String greeting; ... @Execute(validator = false, urlPattern = "hello/{greeting}) public String hello() { ResponseUtil.write(greeting); return null; }
<input type="button" value="hello" onclick="$('#message').load('hello/Hello');"/>
服务
业务逻辑定义在Service里。S2JDBC中已经定义好服务的原型,可以加以利用。
使用S2JDBC的时候,数据库联接的信息定义在jdbc.dicon。jdbc.dicon的配置请参照这里。sa-struts-tutorial工程,jdbc.dicon放置在目录src/main/resources下。
S2JDBC自身的配置在s2jdbc.dicon中。s2jdbc.dicon的配置请参照这里。sa-struts-tutorial工程,s2jdbc.dicon放置在目录src/main/resources下。
S2JDBC通过使用JdbcManager。 服务中使用JdbcManager的时候,如下所示定义变量,并添加注解@Resource。
@Resource protected JdbcManager jdbcManager;
事务处理
SAStruts的事务处理,依靠JTA。JTA的使用在s2container.dicon中进行定义,详细信息请参照这里。sa-struts-tutorial工程,s2container.dicon放置在目录src/main/resources下。
调用Action或者Service方法的时候,自动开始事务处理,是在customizer.dicon中设定。sa-struts-tutorial工程,s2container.dicon放置在目录src/main/resources下。
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> ... </component>
使用TxAttributeCustomizer,调用Object类以外的public方法的时候,自动开始事务处理。 默认的事务处理属性为Required。
Required的时候,如果事务处理没开始,则自动开始,如果已经存在事务处理,则继续操作。 发生异常的时候自动回滚。
如果某个特别类需要改变事务属性的时候,可以在类上追加注解@TransactionAttribute。
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public class XxxAction { ... }
某个特别的方法也可以追加注解@TransactionAttribute。 如下例,someMethod()为TransactionAttributeType.NEVERで、someMethod2()为TransactionAttributeType.REQUIRES_NEW。
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) public class XxxAction { @TransactionAttribute(TransactionAttributeType.NEVER) public void someMethod() { ... } public void someMethod2() { ... } ... }
数据变换
Action和实体进行数据变换的时候,可以使用Beans。 不仅是单纯的值拷贝,也可以进行字符串和数值等的类型变换。Commons BeanUtils没有public变量对应的处理,如果 想对public变量进行变换的时候,请使用Beans。
将使用主键取得的数据拷贝到ActionForm中。
Employee emp = employeeService.findById(Integer.valueOf(employeeForm.id)); Beans.copy(emp, employeeForm).execute();
使用ActionForm的值跟新数据的时候。
Employee emp = Beans.createAndCopy(Employee.class, employeeForm).execute(); employeeService.update(emp);
JSP
JSP保存在Action的目录下。 比如XxxAction对应的JSP保存在/xxx/。
Action或者Action的属性名和 请求的属性名保持一致。如下所示:
${f:h(プロパティ名)} <a href="${f:u(プロパティ名)}">...</a> <c:forEach items="${プロパティ名}" ... ${f:br(f:h(プロパティ名))} <fmt:formatDate value="${f:date(hireDate, 'yyyyMMdd')}" pattern="yyyy/MM/dd"/> <fmt:formatNumber value="${f:number(salary, '####')}" pattern="#,###"/>
需要进行HTML的Escape(为防止XSS将"<"转换成"<")变换的时候,请使用f:h()。f:h()也可以用于显示数组和列。
为防止XSS,需要对URL进行编码的时候请使用f:u()。
EL使用items="${プロパティ名}"这样的定义,为防止XSS,请对tag体使用f:h()。
a标签的href元素,上下文的根目录自动添加的时候,请使用f:url()。 路径以/开始的时候,自动补上根目录路径。 如果不是以/开头的时候,JSP参照的路径。
textArea传入的值表示时,需要通过<br />换行是,使用f:br()。空白就那样表示的时候,使用f:nbsp()。f:br()和f:nbsp()可以组合使用。
${f:br(f:nbsp(f:h(textarea)))}
日付をフォーマットして表示するには、fmt:formatDateを使いますが、value要素に設定する値はDate型である必要があります。Strutsの場合、入力値は、文字列で定義するのが一般的なので、 文字列で定義されている入力値は、fmt:formatDateでフォーマットできません。このような場合は、f:date()を使って文字列をDate型に変換します。2番めの引数は、SimpleDateFormatの形式で指定します。
数值的表示形式需要变换的时候,可以使用fmt:formatNumber、value值必须是Number,如果是字符串则无法使用fmt:formatNumber进行变换。 需要先使用f:number()将字符串转换为Number。 第2个参数为DecimalFormat的形式。
内联的属性可以通过点访问。
${属性名.内联的属性名}
Action或者ActionForm属性,为了public变量可以被EL或者Struts使用、JavaBeans用Map,数组用List进行封装。 属性访问(.)或者数组访问([数値])以外的使用方法,变量的访问请留意。
为了显示任意对象的值,可以使用f:label(value, dataList, valueName, labelName)。value、任意对象的值。dataList是JavaBeans或者Map<String, Object>List等需要表示对象。valueName是value的属性名(Map的时候是键名)、labelName是label的属性名(Map的时候是键名)。
比如想在name属性中显示部门ID的信息,可以如下进行定义。
${f:label(e.departmentId, deptItems, "id", "name")}
どのJSPでも共通で使うような宣言は、1つのJSPにまとめ、web.xmlでそのJSPを指定します。sa-struts-tutorialプロジェクトでは、webapp/WEB-INF/view/common/common.jspに共通で使う宣言が定義されています。
commons.jsp
<%@page pageEncoding="UTF-8"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%> <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <%@taglib prefix="html" uri="http://struts.apache.org/tags-html"%> <%@taglib prefix="bean" uri="http://struts.apache.org/tags-bean"%> <%@taglib prefix="tiles" uri="http://jakarta.apache.org/struts/tags-tiles"%> <%@taglib prefix="s" uri="http://sastruts.seasar.org"%> <%@taglib prefix="f" uri="http://sastruts.seasar.org/functions"%>
web.xml
<web-app> ... <jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <el-ignored>false</el-ignored> <page-encoding>UTF-8</page-encoding> <scripting-invalid>false</scripting-invalid> <include-prelude>/common/common.jsp</include-prelude> </jsp-property-group> </jsp-config> </web-app>
SAStruts在继承Struts的html:form基础上作成了s:form。action属性可以自动生成,如果使用Tiles进行布局的JSP请加上action定义。
SAStruts在继承Struts的html:link基础上作成了s:link。
默认禁止直接跳转到JSP上。如果违反将抛出400错误。JSP首先经过Action然后跳转比较好。
redirect到其他JSP页面时,如下定义返回值。就像经过ActionAction然后跳转一样。
return "/Action/method?redirect=true";
如果必须直接跳转到JSP的时候,web.xml的routingfilter的init-param中的jspDirectAccess设为true。 详细信息请参照web.xml。
Application自动生成
通过使用Dolteng可以自动生成应用。 详细信息请参照Database View。