Chuyển đổi kiểu trong Struts 2



Mọi thứ trên một HTTP request được đối xử như là một String bởi Protocol. Chúng bao gồm các số, các giá trị Boolean, date, giá trị nguyên, thập phân, … Vậy đâu là cách Struts tự động viết các property cho bạn.

Struts sử dụng các kiểu Converter đa dạng để tự động chuyển đổi kiểu cho bạn. Chẳng hạn, nếu bạn có một thuộc tính integer trong lớp Action, Struts tự động chuyển đổi tham số request thành thuộc tính integer mà không cần bạn làm bất cứ điều gì.

Đôi khi, nếu bạn đang sử dụng kiểu dữ liệu riêng, thì việc cần thiết là thêm trình Converter riêng của bạn để làm cho Struts biết cách để chuyển đổi các giá trị đó trước khi hiển thị chúng. Giả sử có lớp POJO có tên Environment.java:

package com.vietjack.struts2;

public class Environment {
   private String name;
   public  Environment(String name)
   {
      this.name = name;
   }
   public String getName() {
      return name;
   }
   public void setName(String name) {
      this.name = name;
   }
}

Lớp đơn giản này có một thuộc tính name. Bây giờ tạo lớp khác mà chứa thông tin về hệ thống, lớp SystemDetails.java. Với mục đích trong chương này, mình đã hardcode Environment thành "Development" và Operating System thành "Windows XP SP3". Trong project thực, bạn sẽ lấy thông tin này từ system configuration. Bây giờ chúng ta có lớp Action sau:

package com.vietjack.struts2;
import com.opensymphony.xwork2.ActionSupport;

public class SystemDetails extends ActionSupport {
   private Environment environment = new Environment("Development");
   private String operatingSystem = "Windows XP SP3";

   public String execute()
   {
      return SUCCESS;
   }
   public Environment getEnvironment() {
      return environment;
   }
   public void setEnvironment(Environment environment) {
      this.environment = environment;
   }
   public String getOperatingSystem() {
      return operatingSystem;
   }
   public void setOperatingSystem(String operatingSystem) {
      this.operatingSystem = operatingSystem;
   }
}

Bây giờ tạo một System.jsp đơn giản để hiển thị thông tin Environment và Operating System:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" 
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>System Details</title>
</head>
<body>
   Environment: <s:property value="environment"/><br/>
   Operating System:<s:property value="operatingSystem"/>
</body>
</html>

Bây giờ, viết system.jsp và SystemDetails.java cùng với nhau bởi sử dụng struts.xml. Lớp SystemDetails có một phương thức execute() mà trả về chuỗi SUCCESS.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name="struts.devMode" value="true" />
   <package name="helloworld" extends="struts-default">
      <action name="system" 
            class="com.vietjack.struts2.SystemDetails" 
            method="execute">
         <result name="success">/System.jsp</result>
      </action>
   </package>
</struts>

Khi triển khai ứng dụng trên, có một vấn đề xảy ra là: Struts biết cách hiển thị và chuyển đổi chuỗi "Windows XP SP3" và các kiểu dữ liệu đã xây dựng sẵn khác, nhưng không biết làm gì với property của kiểu Environment.

Để giải quyết vấn đề này, bây giờ bạn tạo một TypeConverter cho lớp Environment. Tạo lớp EnvironmentConverter.java như sau:

package com.vietjack.struts2;

import java.util.Map;
import org.apache.struts2.util.StrutsTypeConverter;

   public class EnvironmentConverter extends StrutsTypeConverter {
      @Override
      public Object convertFromString(Map context, String[] values, 
                                      Class clazz) {
      Environment env = new Environment(values[0]);
      return env;
   }

   @Override
   public String convertToString(Map context, Object value) {
      Environment env  = (Environment) value;
      return env == null ? null : env.getName();
   }	
}

Lớp EnvironmentConverter kế thừa lớp StrutsTypeConverter và nói cho Struts biết cách chuyển đổi Environment thành một String và ngược lại, bằng cách ghi đè hai phương thức convertFromString()convertToString(). Bây giờ chúng ta đăng ký Converter này trước khi sử dụng nó trong ứng dụng.

Có hai cách để đăng ký một Converter. Nếu Converter chỉ được sử dụng trong một Action cụ thể thì bạn phải tạo một property file có tên dạng '[action-class]'-converstion.properties. Do đó, bây giờ chúng ta tạo một file gọi là SystemDetails-converstion.properties có entry đăng ký như sau:

environment=com.vietjack.struts2.EnvironmentConverter

Trong ví dụ trên, "environment" là tên của thuộc tính trong lớp SystemDetails.java và chúng ta đang nói cho Struts để sử dụng EnvironmentConverter để chuyển đổi sang và từ thuộc tính này. Tuy nhiên, chúng ta không làm điều này, thay vào đó, chúng ta sử dụng cách thứ hai là đăng ký Converter này một cách toàn cục (global) để nó có thể được sử dụng trong cả ứng dụng. Để làm điều này, bạn tạo một property file là xwork-conversion.properties trong WEB-INF/classes folder như sau:

com.vietjack.struts2.Environment = \
            com.vietjack.struts2.EnvironmentConverter

Đó là cách đăng ký toàn cục cho một Converter để Struts có thể tự động chuyển đổi kiểu mỗi khi nó gặp một đối tượng có kiểu Environment ở trên chẳng hạn. Bây giờ, bạn biên dịch và chạy lại chương trình trên sẽ cho kết quả tốt hơn.

Các bài học Struts 2 phổ biến khác tại VietJack: