4.1.2 传统的类型转换

下面以一个简单的应用为例来介绍传统的类型转换。如图4.2所示为用户注册界面,该界面用于收集用户输入的注册信息。注册信息包括:

图4.2 收集注册信息的页面

用户名,该注册信息应该是一个字符串类型。

密码,该注册信息应该是一个字符串类型。

年龄,该注册信息应该是一个数字类型。

生日,该注册信息应该是一个日期类型。

假设本应用提交的数据用于填充一个UserBean,该UserBean类的代码如下。

程序清单:codes\04\4.1\TypeConvert\WEB-INF\src\org\crazyit\struts2\domain\UserBean.java

public class UserBean
{
    //值对象用于封装请求参数的4个属性
    private String name;
    private String pass;
    private int age;
    private Date birth;
    //无参数的构造器
    public UserBean()
    {
    }
    //初始化全部属性的构造器
    public UserBean(String name , String pass , int age , Date birth)
    {
          this.name = name;
          this.pass = pass;
          this.age = age;
          this.birth = birth;
    }
    //name属性的setter和getter方法
    public void setName(String name)
    {
          this.name = name;
    }
    public String getName()
    {
          return this.name;
    }
    //省略其他属性的setter和getter方法
    ...
}

读者可能已经发现,上面的UserBean非常类似于模型驱动下的model类,实际上,我们就是希望在Servlet中使用这个UserBean来封装请求参数。页面收集到的数据提交到regist的Servlet,该Servlet将这些请求信息封装成一个UserBean的值对象。该Servlet的代码如下。

程序清单:codes\04\4.1\TypeConvert\WEB-INF\src\org\crazyit\struts2\web\RegistServlet.java

@WebServlet(urlPatterns="/regist")
public class RegistServlet extends HttpServlet
{
    // Servlet的服务响应方法
    public void service(HttpServletRequest request,
          HttpServletResponse response)throws IOException
    {
          // 设置解码格式
          request.setCharacterEncoding("GBK");
          // 下面4行依次获取4个参数,获取的参数全部为字符串
          String name = request.getParameter("username");
          String pass = request.getParameter("pass");
          String strAge = request.getParameter("age");
          String strBirth = request.getParameter("birth");
          // 下面进行类型转换
          // 字符串类型向整型转换
          int age = Integer.parseInt(strAge);
          // 使用SimpleDateFormat将字符串向日期转换
          // 指定转换格式,日期字符串必须按yyyy-MM-DD格式输入
          SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-DD");
          Date birth = null;
          try
          {
                birth = sdf.parse(strBirth);
          }
          catch (Exception e)
          {
                e.printStackTrace();
          }
          // 将类型转换后的值封装成UserBean值对象
          UserBean user = new UserBean(name , pass , age , birth);
          // 用Servlet直接输出
          response.setContentType("text/html;charset=GBK");
          // 获得页面输出流
          PrintWriter out = response.getWriter();
          out.println("<!DOCTYPE html>");
          out.println("<html>");
          out.println("<head>");
          // 输出页面标题
          out.println("   <title>类型转换页面</title>");
          out.println("</head>");
          out.println("<body>");
          out.println("<h1>类型转换页面</h1>");
          // 下面输出值对象user的4个属性值
          out.println("用户的用户名:" + user.getName() + "<br />");
          out.println("用户的密码:" + user.getPass() + "<br />");
          out.println("用户的年龄:" + user.getAge() + "<br />");
          out.println("用户的生日:" + user.getBirth() + "<br />");
          out.println("</body>");
          out.println("</html>");
    }
}

在上面的示例应用中,我们仅仅对页面输入数据做类型转换,并将其封装成一个UserBean值对象,但未真正将该值对象传入控制逻辑(这是一个 MVC 框架后面将要做的事情),然后直接使用该Servlet生成输出,输出该值对象的属性。

上面的Servlet使用了@WebServlet修饰,该Annotation用于部署该Servlet,该Servlet将位于/regist处对外提供服务。将如图4.2所示表单页面的<form .../>元素的action属性设置为regist,则该表单将提交到该Servlet。

在图4.2所示的页面中依次输入如下注册信息。

(1)在“用户名”文本框中输入aaa。

(2)在“密码”文本框中输入123456。

(3)在“年龄”文本框中输入23

(4)在“生日”文本框中输入1986-01-23。

程序执行的结果如图4.3所示。

图4.3 传统的类型转换

如图4.3所示,用户输入4个字符串参数,经过类型转换后,才可以被封装在一个封装请求参数的值对象里。对于这个应用而言,程序员自己在Servlet中进行类型转换,并将其封装成请求参数的值对象——这些类型转换操作需要程序员来完成,因此比较烦琐。

对于一个MVC框架而言,它一样需要将请求参数封装成VO(Value Object)对象。因此,必须把请求参数转换成VO类里各属性对应的数据类型——这就是类型转换的意义。下面介绍如何利用Struts 2的支持来完成类型转换。