Struts2入門(三)——數據類型轉換

来源:http://www.cnblogs.com/IT-1994/archive/2016/10/25/5998458.html
-Advertisement-
Play Games

一、前言 筆者一直覺得,學習一個知識點,你首先要明白,這東西是什麼?有什麼用?這樣你才能瞭解。好了,不說廢話。 1.1、類型轉換為何存在?什麼是類型轉換? 在MVC框架中,都是屬於表示層解決方案,都需要負責收集用戶請求的參數,並且將請求參數傳給應用的控制器組件,但是,這裡有一個問題,客戶端提交的請求 ...


一、前言

筆者一直覺得,學習一個知識點,你首先要明白,這東西是什麼?有什麼用?這樣你才能瞭解。好了,不說廢話。

1.1、類型轉換為何存在?什麼是類型轉換?

在MVC框架中,都是屬於表示層解決方案,都需要負責收集用戶請求的參數,並且將請求參數傳給應用的控制器組件,但是,這裡有一個問題,客戶端提交的請求參數都是字元串數據類型,而java這門語言本身就是強類型語言,所以我們需要類型轉換,就是把字元串類型轉化為你所需要的類型。

在MVC框架中,表示層數據處理分為兩個方法:客戶端輸入數據,服務端輸出數據;客戶端輸入數據需要進行類型轉換才能確保我們的數據類型是正確的,服務端輸出數據無需經過類型轉換。

簡單說就是:

在javaweb中,當你在jsp頁面提交一個username到servlet中,你是否在通過request.getParameter("username")去獲取數據;但是

如果是一個Date時間類型呢?你是否要先指定時間的轉換格式,然後再根據request.getParameter("date");獲取數據之後再去轉換呢?但是,你想過沒有?如果是多個頁面請求數據的話,那你每次打getParameter();這個方法,累嗎?你不累,程式都累了。所以,Struts2 為我們提供了一種類型轉換器,只需要編寫固定的操作就能得到你想要的數據,簡單說來,就是把表單的數據賦值給實體類。

1.2、類型轉換器簡單介紹

1.2.1、類型轉換器需要繼承DefaultTypeConverter類,需要重寫該類的convertType方法。

convertType方法的作用:

1、負責對類型的轉換,不過這種轉換是雙向的,我們可以通過判斷數據的類型判斷轉換的方向

2、該方法有三個參數:

  context:是類型轉換環境的上下文

  value:    是需要轉換的參數(隨轉換方向不同,如果字元串向實例轉換時,它是字元串數組;如果實例字元串轉換時,它是實例)

  toType: 是轉換後的目標參數

1.2.2、當然,你也可以繼承StrutsTypeConverter是,它是Struts2為我們簡化的類型轉換器,是DefaultTypeConverter的子類,預設產生兩個方法,更加明確的告訴你你要在哪個方法進行轉換,這樣就不用跟繼承DefaultTypeConverter類一樣,通過convertType方法里的參數toType每次去判斷。繼承StrutsTypeConveter該類比較簡單。這裡兩種繼承都有說到。

二、類型轉換器

2.1、類型轉換器有兩種:局部類型轉換器和全局類型轉換器,就字面上的意思一樣,全局和局部的。

關於類型轉換器的註冊方式有三種:

1、局部類型轉換器僅僅對某個Action起作用

2、全局類型轉換器對所有Action特定類型的屬性都會起作用

3、我們可以通過註解的方式來生成類型轉換器(JDK1.5以上的註解)

2.2、局部類型轉換器:

新建實體類userbean:

package com.TypeConverter;

import java.util.Date;

public class userbean {
    private String uname;
    private String upwd;
    private int uage;
    private Date udate;
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public String getUpwd() {
        return upwd;
    }
    public void setUpwd(String upwd) {
        this.upwd = upwd;
    }
    public int getUage() {
        return uage;
    }
    public void setUage(int uage) {
        this.uage = uage;
    }
    public Date getUdate() {
        return udate;
    }
    public void setUdate(Date date) {
        this.udate = date;
    }
    public userbean(){
}
    public userbean(String uname, String upwd, int uage, Date udate) {
        this.uname = uname;
        this.upwd = upwd;
        this.uage = uage;
        this.udate = udate;
    }
}    
userbean

 

建立jsp視圖:這裡的是Test.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>局部類型轉換器</title>
</head>
<body>
    <h2>請輸入您的註冊信息</h2>
    <form action="user">
    <!-- 註意:name的名字必須是userbean1,跟useraction裡面屬性名字一樣 -->
    <label>用戶名:</label><input type="text" name="userbean1"><br/>
    <label>&nbsp;碼:</label><input type="text" name="userbean1"><br/>
    <label>&nbsp;齡:</label><input type="text" name="userbean1"><br/>
    <label>&nbsp;日:</label><input type="text" name="userbean1"><br/>
    <input type="submit">
    </form>
</body>
</html>

 

在struts.xml配置信息。我們只需要配置這個

 這裡的<result name="input">是錯誤機制處理程式,就是說當頁面跳轉錯誤或者異常問題的時候,會跳轉到你指定的頁面,這裡筆者是讓其自動跳轉到原來的頁面。

我們可以定義一個局部的錯誤處理消息提示,這裡筆者沒有做,但是可以瞭解下:

新建useraction.properties,放在同級目錄下,
這裡的useraction是值你繼承ActionSupport的類,然後往該文件中寫入:
invalid.fieldvalue.屬性名=提示消息(其中屬性名可以是:uname或者upwd等)
當類型轉換錯誤就會跳轉,你可以在頁面上使用JSTL列印,如:
<%@ taglib uri="/struts-tags" prefix="s"%>    
然後使用<s:fielderror/>該標簽顯示出你的提示消息
錯誤消息處理機制

 

新建useraction類,繼承ActionSupport。

package com.TypeConverter;

import com.opensymphony.xwork2.ActionSupport;

//使用的是局部的類型轉化器
public class useraction extends ActionSupport {
    private userbean userbean1;
    public userbean getUserbean1() {
        return userbean1;
    }
    public void setUserbean1(userbean userbean1) {
        this.userbean1 = userbean1;
    }
    public String execute(){
        System.out.println(userbean1.getUname());
        System.out.println("useraction");
        return SUCCESS;
    }
}

 

重點來了:我們需要新建類去繼承DefaultTypeConverter,然後重寫裡面的方法。

這裡的類名是TestType

package com.TypeConverter;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Map;

import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;

//
public class TestType extends DefaultTypeConverter {
    @Override
    public Object convertValue(Map<String, Object> context, Object value, Class toType) {
        //需要將字元串向userbean類型轉換時
        if(toType==userbean.class){
            //系統的請求參數是一個字元串數組
            System.out.println("TestType");
            String params[] = (String[]) value;
            userbean user = new userbean();
            user.setUname(params[0]);
            user.setUpwd(params[1]);
            user.setUage(Integer.parseInt(params[2]));
            SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");
            try {
                user.setUdate(s.parse(params[3]));
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return user;
        }else if(toType==String.class){
            userbean user = (userbean) value;
            System.out.println("--------------------");
            return "<"+user.getUname()+">";
        }
        System.out.println("--------------------");
        return null;
    }
}

在這裡筆者遇到一點小問題:就是使用

SimpleDateFormat s = new SimpleDateFormat("yyyy-MM-dd");

s.format(param[3]);

一直報錯誤:Unexpected Exception caught setting 'userbean1' on 'class com.TypeConverter.useraction: Error setting expression 'userbean1' with value ['admin', '123', '20', '1992-1-2', ],直到我把userbean中的udate類型改為Date類型才能夠正常走,並且把s.format換成s.parse(param[3])。疑惑。

筆者測試代碼走的順序:

先走繼承DefaultTypeConverter類的TestType,然後跳轉到useraction類中的execute方法。

註意:我們還需要在建一個文件,告訴程式說,我們要把數據填充到類是哪一個?新建Actionname-conversion.properties

其中-conversion.properties是固定的,需要改變只是Actionname(表示繼承ActionSupport的類,這裡是useraction。對應struts.xml的class)

新建useraction-conversion.properties。放在同級目錄下:

該文件的內容有:

這裡的userbean1是你在useraction中實例化的名字。

後面的TestType是你繼承DefaultTypeConverter類的名字。這裡是TestType

代碼運行結果如下:

Test.jsp界面

target.jsp界面效果:

target.jsp的代碼:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>類型轉化器輸出結果</title>
</head>
<body>
    用戶名:${userbean1.uname }<br/>
    密碼:${userbean1.upwd }<br/>
    年齡:${userbean1.uage }<br/>
    生日:${userbean1.udate }<br/>
</body>
</html>
target.jsp的代碼

 

2.3、全局類型轉換

2.3.1、對指定的類型的全部屬性有效。基本操作一樣,只是有一點不同,properties文件放的位置和名字不同。

新建jsp頁面,頁面名:Test1.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>使用全局的類型轉換器</title>
</head>
<body>
    <h2>使用全局的類型轉換器</h2>
    <form action="Stubean">
    <label>用戶名:</label><input type="text" name="stu"><br/>
    <label>&nbsp;齡:</label><input type="text" name="stu"><br/>
    <input type="submit">
    </form>
</body>
</html>
Test1.jsp

 

新建實體類StuBean:

package com.TypeConverter.global;

public class StuBean {
    private String uname;
    private int uage;
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public int getUage() {
        return uage;
    }
    public void setUage(int uage) {
        this.uage = uage;
    }
}
StuBean

 

配置struts.xml

 

新建StuAction類繼承ActionSupport

package com.TypeConverter.global;

import com.opensymphony.xwork2.ActionSupport;

//使用全局的類型轉換器
//執行順序:類型轉換器——>execute

public class StuAction extends ActionSupport {
    private StuBean stu;

    public StuBean getStu() {
        return stu;
    }

    public void setStu(StuBean stu) {
        this.stu = stu;
    }
    
    public String execute(){
        System.out.println("StuAction");
        System.out.println(stu.getUname());
        return SUCCESS;
    }
}
StuAction

 

 

新建GlobalTypeConverter類繼承StrutsTypeConverter,這裡的StrutsTypeConverter是簡化類型轉換器,它是DefaultTypeConverter的子類。以下是代碼:

package com.TypeConverter.global;

import java.util.Map;

import org.apache.struts2.util.StrutsTypeConverter;


public class GlobalTypeConverter extends StrutsTypeConverter {
    
    //轉化為javabean對象
    @Override
    public Object convertFromString(Map arg0, String[] arg1, Class arg2) {
        System.out.println("Global...");
        StuBean stu = new StuBean();
        stu.setUname(arg1[0]);
        stu.setUage(Integer.parseInt(arg1[1]));
        return stu;
    }

    //轉化為String對象
    @Override
    public String convertToString(Map arg0, Object arg1) {
        StuBean s = (StuBean)arg1;
        return s.getUname()+"!!";
    }

}
GlobalTypeConverter

 

註意:全局與局部不同的地方在於properties文件名和放的位置不同,全局的文件名為:xwork-conversion.properties

位置在:

放在classes之下,有些沒有classes文件,需要自己創建。

內容為:

前面的是該StuBean實體類的路徑,後面的是繼承StrutsTypeConverter類的類型轉換器

如果要設置錯誤處理消息的話,我們可以添加一行代碼,當頁面出錯的時候提示,這裡筆者沒有做,但是可以瞭解,添加代碼為:

xwork.default.invalid.fieldvalue=提示消息

顯示效果上面有介紹。如果你需要的話可以使用。

代碼運行結果為:

Test1.jsp界面

target1.jsp界面

有誰能介紹一個錄製操作的軟體,謝謝。

以上就是Struts2 類型轉換器的基本知識,有不足的請下方留言。謝謝。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 英文文檔: 2. 不傳入參數時,生成的空的不可變集合。 ...
  • JVM記憶體區域 我們在編寫程式時,經常會遇到OOM(out of Memory)以及記憶體泄漏等問題。為了避免出現這些問題,我們首先必須對JVM的記憶體劃分有個具體的認識。JVM將記憶體主要劃分為:方法區、虛擬機棧、本地方法棧、堆、程式計數器。JVM運行時數據區如下: 程式計數器 程式計數器是線程私有的區 ...
  • 1、什麼是序列化?為什麼要序列化? Java 序列化就是指將對象轉換為位元組序列的過程,而反序列化則是只將位元組序列轉換成目標對象的過程。 我們都知道,在進行瀏覽器訪問的時候,我們看到的文本、圖片、音頻、視頻等都是通過二進位序列進行傳輸的,那麼如果我們需要將Java對象進行傳輸的時候,是不是也應該先將對 ...
  • 背景 做為一名使用高級語言的程式員,面向對象的設計一直都是體現程式員能力的重要標準之一,所以在我工作兩年後也就是2008年我也開始了對於面向對象設計的學習,主要是拿GOF設計模式來練手,儘管實際項目中沒有真正的使用過。常見的23種設計模式,我從2008一至到2009年將近一年的時間我基本上將這些模式 ...
  • 單例模式一般應用在整個應用中只會存在一個對象。比如應用類,游戲場景類,工具類等。 實現方式: 頭文件 singleton.h: #ifndef _SINGLETON_H_ #define _SINGLETON_H_ class CSingleton{ public: //供外部調用,通過此方法獲取實 ...
  • 一、前言 1.1、什麼是輸入驗證?為什麼需要輸入驗證? 在上一篇文章中,我們學習了數據類型轉換,我們提到了表示層數據處理的兩個方法,也提到了用戶輸入數據需要進行類型轉換才能得到我們想要的數據,那麼,我們怎麼確定類型轉換後的數據,是我們想要的數據呢?這裡有點繞。你可以這樣想:一個成年男子年齡是18歲, ...
  • 以需求用例為基,抽象介面,Case&Coding兩條線並行,服務(M)&消費(VC)分離,單元、介面、功能、集成四層質量管理,自動化集成、測試、交付全程支持。 3個大階段(需求分析階段、研發準備階段、研發測試階段)16個小歷程(*)確定好邊界,明確好對接產物,做好服務管理。 基於SOA架構的TDD測 ...
  • 這個問題是不可迴避的 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...