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

Global site tag (gtag.js) - Google Analytics