cetia4学习笔记(3)
tou3921
2008-09-18
http://our.bizairshop.com/note/post/cetia4-3.html
5.2 POST/PUT/DELETE HTTP请求的path info // 对应 http://example.com/forum/topics public String update( ActionContext context ) { return "topics"; } // 对应 http://example.com/forum/topics/46 public String update( ActionContext context, int id ) { return "topics/15"; } // 对应 http://example.com/forum/topics/es/456 public String update( ActionContext context, String lang, int id ) { return "topics/en/15"; } 当发起POST请求到 /forum/topics 如果post data中有 _method=insert 则 访问 public String insert(ActionContext ); _method=delete 则 访问 public String delete(ActionContext ); _method=consolidate 则访问 public String consolidate( ActionContext ); 如果post参数中没有_method值,则访问 public String update(ActionContext ); post中传输的参数不在url中,而是编码之后在post body的data中 5.4 HTTP方法限制 因为如果一个响应方法不作限制,只要_method参数值作改变,POST/PUT/DELETE方法都可以调用 任意的方法响应。例如 DELETE方法访问 /forum/topics ,是 public String delete(ActionContext) 去响应, 用POST方法访问 /forum/topics,同时post参数中带_method=delete,则也是那个方法去响应。 现在要限制这个方法只能响应DELETE请求,不能响应POST请求,这么做: @Method( answers=HttpMethod.DELETE ) public String delete( ActionContext context, TopicDTO topic ) 5.5 ServletRequestContext 跟render方法一样,当ActionContext需要具体化成跟servlet相关的对象时,使用ServletRequestContext public String update( ServletRequestContext context ) { HttpServletRequest request = context.getServletRequest(); return "topics"; } ServletRequestContext扩充了RenderRequest和ActionRequest两个接口。 5.6 ActionContext的方法 ActionContext的方法跟RenderContext的方法基本一样,只是多了处理带上传文件表单的方法(//@TODO) Render参数概念是从portlet借鉴的,可以更优雅的创建url参数。例如: public String update( ActionContext context ) { return "topics?_method=list&format=plain"; } 相当于 public String update( ActionContext context ) { context.setRenderParameter( "_method", "list" ); context.setRenderParameter( "format", "plain" ); return "topics"; } 而且,在web service请求中,render参数也可以使用,并存储在request级别的名为_render_parameters的map中。 可以通过如下访问: <?xml version="1.0" encoding="ISO-8859-1"?> <jsp:root version="2.0" xmlns:jsp="http://java.sun.com/JSP/Page" xmlns:c="http://java.sun.com/jsp/jstl/core"> <jsp:directive.page contentType="application/xml" session="false"/> <response> <c:forEach var="renderParam" items="${ _render_parameters }"> <renderParam name="${ renderParam.key }" value="${ renderParam.value }"> ${ renderParam.key } = ${ renderParam.value } </renderParam> </c:forEach> </response> </jsp:root> 需要注意的是:不能有同名参数。 5.7 错误页面 一个action方法可能抛出异常,或者放回LOAD_ERROR特定参数值到达错误页面。 但是这个错误页面一般都在受保护的目录如 /WEN-INF/html/error.jsp,因此需要一个 redirect转向的servlet。cetia4已经提供了这样的转向servlet,定义如下: <servlet> <description> Error Handler. </description> <servlet-name>error</servlet-name> <servlet-class> com.acsinet_solutions.cetia4.controller.support.ErrorServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>error</servlet-name> <url-pattern>/error</url-pattern> </servlet-mapping> 流程如下: a. http PUT访问 /forum/topics b. 执行 public String insert(ActionServlet) { return LOAD_ERROR; //或者 抛出一个异常 } c. sendRedirect( "/forum/error" ); d. GET /forum/error 到ErrorServlet e. 转到 /WEB-INF/html/error.jsp 在web service请求中,HTTP Get redirect转向不支持,更加简单的直接转向error view 6. Mapping 映射 从HTTP parameter映射到java bean public String methodName( ActionContext|RenderContext context, zero or more String or primitive path-info arguments, zero or one list or array multiple-depth arguments, zero or one object arguments for parameter mapping ) 最后一个参数是可以从HTTP parameter值直接设置到的参数对象。 参数对象只需要满足两点要求即可:(1)有一个默认的无参数构造函数 (2)属性值有setter方法 例如: public String insert( ActionContext context, TopicDTO topic ) { // work with topic... return "topics"; } public String insert( ActionContext context, TopicDTO topic ) { // work with topic... return "topics"; } public String insert( ActionContext context, TopicDTO topic ) { // work with topic... return "topics"; } mapping参数对象只能有一个,下面的会出错! // ERROR: THIS WON'T WORK - AN EXCEPTION WILL BE THROWN public String update( ActionContext context, TopicDTO topic, AnotherDTO another ) { return "topics"; } 6.1 默认映射 默认的映射类型支持有: String , int, long , Integer, Long float, double, Float, Double boolean, Boolean ("true"/"false", 0/1) java.util.Time ( "hh:mm" ) java.util.Date/Calendar ( "dd/MM/yyyy" ) java.math.BigDecimal ( //@TODO 我还没看 ) Enumerated Properties List 6.2 Validation 校验 当有值不能转换到目标类型在映射或者path info参数绑定时,验证异常将会抛出。 例如: (1) POST 请求到 http://example.com/forum/topics/grrrrr 因为处理函数是 public String update(ActionContext, int id, TopicDTO topic) grrrr字符串不能转换成int类型,所以有校验错误 (2) POST 请求到 http://example.com/forum/topics/123 但是post值中的date参数是"invalid!!!",不能转换成java.util.Calendar类型 这些情况都会抛出验证一场,Cetia4框架中的验证异常是实例化 com.acsinet_solutions.util.exception.ValidationException (验证异常是通过一个或者多个验证事件组成,验证事件是 com.acsinet_solutions.util.validator.ValidationIssue 类 ,可以国际化或者不) 如果国际化则用 com.acsinet_solutions.util.text.global_messages; 定义的 ValidationException是检测异常类,非检测异常类是 com.acsinet_solutions.util.exception.ValidationRuntimeException 验证和映射都可以自定义(//@TODO) 处理验证异常的3种情况: (1) 传统web和web service请求的render方法,验证异常都把执行forward到错误view页面, 所有的验证异常处理页面都是一个view。 如:/forum/topics/INVALID 抛出Validation Exception, web访问 转到 /WEB-INF/html/error.jsp web service 访问 转到 /WEB-INF/html/error.jsp |