Ch13-2 : Edit Profile 1

[Profile 1]

這個小節我們要設計會員明細資料,回顧我們的member_main這個表單設計,還有使用者名稱沒有開放修改,也會納入修改會員資料的範圍。

那我們這次會員資料的編輯,是為了補足註冊時,沒有填寫的詳細資料,參考目前主流的社群平台之後,我這次會新增一個會員明細資料表與資料log表。這個資料表是member_detail,那這個資料表基本欄位會有頭像的連結、生日、手機、暱稱這四個欄位,資料表的primary key會是member_mainmemberNo。
不過各位可能會有疑問,為什麼不開放儲存照片檔案,這樣我們資料表設計就得考慮到額外空間去儲存使用者的頭像,為了減少複雜,我這次只給新增頭像連結即可。

那以下開始說明如何完成這個小節。


[設計階段]

這次我們這個小節,會採用網頁目前流行的ajax(非同步的JavaScript與XML技術)方式讓使用者去編輯會員資料,依照我們想要的修改資料部分有member_mainusername與要新增的member_detailnicknamebirthdaycellphoneheaderPicLink這四個欄位,總計會要修改五個欄位需要填寫。

因為這次採用ajax去即時檢核使用者輸入這些欄位時,需要的5個ajax檢核使用者的輸入是否正確,除了useranme(使用者名稱)必須填寫之外,剩下四個欄位檢核,使用者可以填寫或不填寫都可以,最後一樣使用ajax進行所有資料驗證,確認可以之後,才允許使用者去做新修改或新增的動作。

因為這次頁面採用全ajax處理頁面上的會員編輯,那我們的驗證欄位的回傳格式會一律是Json格式,裡面會有一些狀態代碼,狀態說明,以及該欄位是否檢核成功,目的是為了一致性,這樣我們在撰寫相關JS時會比較統一,那以下開始介紹相關表單與相關程式。


[相關表單] member_detail

會員明細資料,當使用者使用編輯會員資料時,會寫入或更新以下資訊。

-- 會員明細
-- member_detail
-- memberNo    會員編號
-- headerPicLink 頭像網址
-- birthday 生日
-- nickname 暱稱
-- cellphone 手機號碼
-- createDate 建立日期
-- modifyDate 修改日期

CREATE TABLE `member_detail` (
    `memberNo`       VARCHAR(15)  NOT NULL NULL COLLATE 'utf8_unicode_ci',
    `nickname`          VARCHAR(50)  NULL NULL COLLATE  'utf8_unicode_ci',
    `birthday`          VARCHAR(50)  NULL NULL COLLATE 'utf8_unicode_ci',
    `cellphone`     VARCHAR(50)  NULL NULL COLLATE 'utf8_unicode_ci',
    `headerPicLink` VARCHAR(500) NULL NULL COLLATE 'utf8_unicode_ci',
    `createDate` VARCHAR(50)  NOT NULL NULL COLLATE 'utf8_unicode_ci',
    `modifyDate` VARCHAR(50)  NOT NULL NULL COLLATE  'utf8_unicode_ci',
     CONSTRAINT pk_memberNo PRIMARY KEY (memberNo),
     INDEX (cellphone) 
)COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

member_detail_log

會員明細修改紀錄表,這個表的設計是為了紀錄使用者的修改紀錄

-- 會員明細修改紀錄表
-- member_detail
-- memberNo    會員編號
-- headerPicLink 頭像網址
-- birthday 生日
-- nickname 暱稱
-- cellphone 手機號碼
-- createDate 建立日期

CREATE TABLE `member_detail_log` (
    `memberNo`       VARCHAR(15)  NOT NULL NULL COLLATE 'utf8_unicode_ci',
    `nickname`          VARCHAR(50)   NULL NULL COLLATE  'utf8_unicode_ci',
    `birthday`          VARCHAR(50)   NULL NULL COLLATE 'utf8_unicode_ci',
    `cellphone`     VARCHAR(50)   NULL NULL COLLATE 'utf8_unicode_ci',
    `headerPicLink` VARCHAR(500)  NULL NULL COLLATE 'utf8_unicode_ci',
    `createDate` VARCHAR(50)  NOT NULL NULL COLLATE 'utf8_unicode_ci',
     index (memberNo)
)
COLLATE='utf8_unicode_ci'
ENGINE=InnoDB
;

[相關程式路徑]

app
 └ controllers
   └ WebController.java               <-- 新增Edit Profile相關功能
 └ pojo
   └ web
     └ MemberDetail.java              <--- 新增會員明細資料
       MemberProfile.java             <--- 頁面會員編輯資料
     └ signup
        └ status
          └ BirthDayStatus.java       <--- 生日檢核狀態
            CellphoneStatus.java      <--- 手機檢核狀態
            HeaderPicLinkStatus.java  <--- 頭像檢核狀態
            NicknameStatus.java       <--- 暱稱檢核狀態
            UpdateMemberProfileStatus.java  <--- 更新會員資料狀態
            UsernameStatus.java       <--- 調整使用者名稱檢核狀態
        └ update.java
          └ UpdateMessage.java        <--- 更新結果訊息 
            UpdateType.java           <--- 更新類型種類
        └ verific
          └ VerificCheckMessage.java  <--- 檢查欄位資訊是否正確 
 └ services
   └ Impl
     └ WebServiceImpl.java            <--- 實作WebService的新功能
   └ WebService.java                  <--- 新增會員明細相關DB服務
 └ utils
   └ enc
     └ EncAndDeCodeTool.java          <--- 加解密工具  
   └ http
     └ HttpHelper.java                <--- Http工具
   └ signup
     └ Utils_Signup.java              <--- 新增會員明細相關功能
 └ views
   └ web
      └ headerJqueryuiLibs.scala.html <--- 新增Jqeury 日期選擇器相關libary
        headerNav.scala.html          <--- 調整新增會員編輯連結
      └ loginSignup
        └ editProfile.scala.html      <--- 編輯會員資料頁面
conf
 └ routes                             <--- 新增相關會員編輯服務
 └ services
   └ WebService.xml                   <--- 新增會員編輯相關SQL
public
 └ sql
   └ profile.sql                      <--- 會員編輯相關Table資料 
 └ javascripts
   └ profileUtils.js                  <--- 會員編輯主要js
     webUtils.js                      <--- 公用Web主要js
   └ jquery-ui-1.12.1
      └ LICENSE.txt                   <--- jqeury ui說明
        datepicker-zh-TW.js           <--- jqeury Ui繁體中文js
        jquery-1.12.4.js              <--- jquery ui需要的js
        jquery-ui.css                 <--- jquery ui主要樣式表
        jquery-ui.js                  <--- jquery ui主要js
        package.json                  <--- jquery ui主要的檔案相依性
        images
         └ calendar.gif               <--- 日期選擇器的icon圖 
           ui-icons_444444_256x240.png <--- 日期選擇器相關圖
           ui-icons_555555_256x240.png 
           ui-icons_777620_256x240.png 
           ui-icons_777777_256x240.png 
           ui-icons_cc0000_256x240.png 
           ui-icons_ffffff_256x240.png

[後端相關程式]

在寫這個章節時,實際上,我是依序把每個欄位的功能,逐一實作出來,邊寫邊調整,逐漸規劃出比較合適的寫法,這個小節會介紹後端相關功能,下一個小節介紹前端頁面需要的頁面與JS,最後一個小節是進行測試與驗證,來完成編輯會員明細的功能。

app.pojo.web.MemberDetail.java
使用者的會員明細資料,裡面會有頭像、生日、手機、暱稱這四個欄位,主要用途是寫入資料庫,或讀取明細所使用。

package pojo.web;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class MemberDetail {

  private String memberNo;

  private String nickname;

  private String birthday;

  private String cellphone;

  private String headerPicLink;

  private String createDate;

  private String modifyDate;

  public String getMemberNo() {
    return memberNo;
  }

  public void setMemberNo(String memberNo) {
    this.memberNo = memberNo;
  }

  public String getNickname() {
    return nickname;
  }

  public void setNickname(String nickname) {
    this.nickname = nickname;
  }

  public String getBirthday() {
    return birthday;
  }

  public void setBirthday(String birthday) {
    this.birthday = birthday;
  }

  public String getCellphone() {
    return cellphone;
  }

  public void setCellphone(String cellphone) {
    this.cellphone = cellphone;
  }

  public String getHeaderPicLink() {
    return headerPicLink;
  }

  public void setHeaderPicLink(String headerPicLink) {
    this.headerPicLink = headerPicLink;
  }

  public String getCreateDate() {
    return createDate;
  }

  public void setCreateDate(String createDate) {
    this.createDate = createDate;
  }

  public String getModifyDate() {
    return modifyDate;
  }

  public void setModifyDate(String modifyDate) {
    this.modifyDate = modifyDate;
  }


}

app.pojo.web.MemberProfile.java

這個類別設計,是因為混合了Member與MemberDetail的欄位資訊,設計出單純給會員編輯頁面使用。

package pojo.web;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class MemberProfile {

  private String username;

  private String nickname;

  private String birthday;

  private String cellphone;

  private String headerPicLink;

  private boolean editable;

  private String systemMessage;

  public MemberProfile(){
    this.username = "";
    this.nickname = "";
    this.birthday = "";
    this.cellphone = "";
    this.headerPicLink = "";
    this.editable = false;
    this.systemMessage = "系統異常,請稍候再嘗試。";
  }

  public String getUsername() {
    return username;
  }

  public void setUsername(String username) {
    this.username = username;
  }

  public String getNickname() {
    return nickname;
  }

  public void setNickname(String nickname) {
    this.nickname = nickname;
  }

  public String getBirthday() {
    return birthday;
  }

  public void setBirthday(String birthday) {
    this.birthday = birthday;
  }

  public String getCellphone() {
    return cellphone;
  }

  public void setCellphone(String cellphone) {
    this.cellphone = cellphone;
  }

  public String getHeaderPicLink() {
    return headerPicLink;
  }

  public void setHeaderPicLink(String headerPicLink) {
    this.headerPicLink = headerPicLink;
  }

  public boolean isEditable() {
    return editable;
  }

  public void setEditable(boolean editable) {
    this.editable = editable;
  }

  public String getSystemMessage() {
    return systemMessage;
  }

  public void setSystemMessage(String systemMessage) {
    this.systemMessage = systemMessage;
  }

}

app.pojo.web.signup.status.BirthDayStatus.java
這個類別是針對會員明細的生日作檢核的資訊,裡面描述填寫生日時,相關檢核結果。

package pojo.web.signup.status;

public enum BirthDayStatus {

  /** 生日格式不正確,請重新選擇。 */
  S1("1", "生日格式不正確,請重新選擇。" , false),

  /** 生日超過現在時間,請重新選擇。 */
  S2("2", "生日超過現在時間,請重新選擇。" , false),

  /** 生日正確。*/
  S200("200", "生日正確。" , true) ,

  /** 生日無輸入,不需要顯示說明*/
  S201("201", "" , true) ,

  /** 生日與DB生日一致,不需要顯示說明*/
  S202("202", "" , true)
  ;

  BirthDayStatus(String status, String statusDesc , boolean pass) {
    this.status = status;
    this.statusDesc = statusDesc;
    this.pass = pass;
  }

  /** 狀態代碼 */
  public final String status;

  /** 狀態說明 */
  public final String statusDesc;

  /** 欄位驗證是否可以通過 */
  public final boolean pass;   

}

app.pojo.web.signup.status.CellphoneStatus.java
這個類別是針對會員明細的手機作檢核的資訊,裡面描述填寫手機時,相關檢核結果。

package pojo.web.signup.status;

public enum CellphoneStatus {

  S1("1", "手機號碼格式不正確,請重新輸入。" , false),

  S2("2", "該手機號碼已在使用中,請重新輸入。" , false),

  S200("200", "手機號碼可以使用。" , true) ,

  /** 手機號碼無輸入,不需要顯示說明 */
  S201("201", ""  , true) ,

  /** 手機號碼為同一人,不需要顯示說明 */
  S202("202", ""  , true)
  ;

  CellphoneStatus(String status, String statusDesc , boolean pass) {
    this.status = status;
    this.statusDesc = statusDesc;
    this.pass = pass;
  }

  /** 狀態代碼 */
  public final String status;

  /** 狀態說明 */
  public final String statusDesc;

  /** 欄位驗證是否可以通過 */
  public final boolean pass;   

}

app.pojo.web.signup.status.HeaderPicLinkStatus.java
這個類別是針對會員明細的頭像作檢核的資訊,裡面描述填寫頭像時,相關檢核結果。

package pojo.web.signup.status;

public enum HeaderPicLinkStatus {

  /** 圖片網址不正確,請重新輸入。 */
  S1("1", "圖片網址不正確,請重新輸入。" , false),

  /** 圖片網址無法載入圖片,請重新輸入。 */
  S2("2", "圖片網址無法載入圖片,請重新輸入。" , false),

  /** 圖片網址可以使用。*/
  S200("200", "圖片網址可以使用。" , true) ,

  /** 圖片網址無輸入,不需要顯示說明*/
  S201("201", "" , true) ,

  /** 圖片網址相同,不需要顯示說明*/
  S202("202", "" , true)
  ;

  HeaderPicLinkStatus(String status, String statusDesc , boolean pass) {
    this.status = status;
    this.statusDesc = statusDesc;
    this.pass = pass;
  }

  /** 狀態代碼 */
  public final String status;

  /** 狀態說明 */
  public final String statusDesc;

  /** 欄位驗證是否可以通過 */
  public final boolean pass;   

}

app.pojo.web.signup.status.NicknameStatus.java

這個類別是針對會員明細的暱稱作檢核的資訊,裡面描述填寫暱稱時,相關檢核結果。

package pojo.web.signup.status;

public enum NicknameStatus {

  /** 暱稱長度只能且介於1個字~15字之間。 */
  S1("1", "暱稱長度只能且介於1個字~15字之間。" , false),

  /** "暱稱不能含有特殊字元,請您重新輸入。 */
  S2("2", "暱稱不能含有特殊字元,請您重新輸入。" , false), 

  /** 暱稱可以使用。 */
  S200("200", "暱稱可以使用。" , true) ,

  /** 暱稱無輸入,不需要顯示說明 */
  S201("201", "" , true) ,

  /** 暱稱相同,不需要顯示說明 */
  S202("202", "" , true) ,
  ;

  NicknameStatus(String status, String statusDesc , boolean pass) {
    this.status = status;
    this.statusDesc = statusDesc;
    this.pass = pass;
  }

  /** 狀態代碼 */
  public final String status;

  /** 狀態說明 */
  public final String statusDesc;

  /** 欄位驗證是否可以通過 */
  public final boolean pass;   

}

app.pojo.web.signup.status.UsernameStatus.java

這個類別是針對會員的使用者名稱作檢核的資訊,裡面描述填寫使用者名稱時,相關檢核結果。這個類別之前使用在會員註冊,這次調整成,可以符合修改會員資料的格式。

package pojo.web.signup.status;

public enum UsernameStatus {

  /** 請輸入使用者名稱。*/
  S1("1", "請輸入使用者名稱。" , false),

  /** 使用者名稱只能使用英文字,且介於4個字~15字之間。 */
  S2("2", "使用者名稱只能使用英文字,且介於4個字~15字之間。", false), 

  /** 該使用者名稱已被使用,請改用其它名稱。 */
  S3("3", "該使用者名稱已被使用,請改用其它名稱。" , false), 

  /** 使用者名稱可以使用。 */
  S200("200", "使用者名稱可以使用。" , true) ,

  /** 使用者名稱與原本相同,不顯示任何文字訊息*/
  S201("201", "" , true),
  ;


  UsernameStatus(String status, String statusDesc , boolean pass) {
    this.status = status;
    this.statusDesc = statusDesc;
    this.pass = pass;
  }

  /** 狀態代碼 */
  public final String status;

  /** 狀態說明 */
  public final String statusDesc;

  /** 欄位驗證是否可以通過 */
  public final boolean pass;   

}

app.pojo.web.signup.status.UpdateMemberProfileStatus.java

這個類別是針對編即會員的整體檢核資訊,裡面描述編輯會員明細時,整體檢核結果。

package pojo.web.signup.status;

public enum UpdateMemberProfileStatus {

  /** 系統忙碌中,請稍後再編輯您的會員資料,謝謝。 */
  SE1("SE1", "系統忙碌中,請稍後再編輯您的會員資料。" , false),

  /** 您的會員資料修改有誤,請檢查以上填寫資訊是否正確,謝謝。 */
  E1("E1" , "您的會員資料修改有誤,請檢查以上填寫資訊是否正確,謝謝。" , false),

  /** 您的會員資料,更新成功。*/
  S200("S200", "會員資料編輯成功。" , true)

  ;

  UpdateMemberProfileStatus(String status, String statusDesc , boolean update) {
    this.status = status;
    this.statusDesc = statusDesc;
    this.update = update;
  }

  /** 狀態代碼 */
  public final String status;

  /** 狀態說明 */
  public final String statusDesc;

  /** 是否更新成功 */
  public final boolean update;   

}

app.pojo.web.signup.verific.VerificCheckMessage.java
這個類別用途是針對這次編輯會員方式,新增的類別,主要跟VerificFormMessage.java區別是多增加了pass欄位讓前端知道是否檢核成功。

package pojo.web.signup.verific;

/**
 * 檢查欄位資訊是否正確
 * 並新增boolean值檢視欄位是否通過
 */
public class VerificCheckMessage extends VerificFormMessage {

  private boolean pass;

  public boolean isPass() {
    return pass;
  }

  public void setPass(boolean pass) {
    this.pass = pass;
  }

}

app.pojo.web.signup.update.UpdateMessage.java
這個類別設計用途是,使用者填寫所有欄位時,相關的更新訊息與相關欄位檢核的資訊。

package pojo.web.signup.update;

import java.util.Map;

import pojo.web.signup.verific.VerificCheckMessage;

/**
 * 更新結果訊息 
 */
public class UpdateMessage {

  // 更新類型
  private String updateType;

  // 狀態碼
  private String status;

  // 狀態碼描述
  private String statusDesc;

  // 是否更新成功
  private boolean update;

  // 檢驗結果
  private Map<String , VerificCheckMessage> verificResults;

  // 耗費時間
  private String costTime;

  public String getUpdateType() {
    return updateType;
  }

  public void setUpdateType(String updateType) {
    this.updateType = updateType;
  }

  public String getStatus() {
    return status;
  }

  public void setStatus(String status) {
    this.status = status;
  }

  public String getStatusDesc() {
    return statusDesc;
  }

  public void setStatusDesc(String statusDesc) {
    this.statusDesc = statusDesc;
  }

  public boolean isUpdate() {
    return update;
  }

  public void setUpdate(boolean update) {
    this.update = update;
  }

  public Map<String, VerificCheckMessage> getVerificResults() {
    return verificResults;
  }

  public void setVerificResults(Map<String, VerificCheckMessage> verificResults) {
    this.verificResults = verificResults;
  }

  public String getCostTime() {
    return costTime;
  }

  public void setCostTime(String costTime) {
    this.costTime = costTime;
  }

}

app.pojo.web.signup.update.UpdateType.java
這個類別用途是給UpdateMessage這個類別所區別,讓使用者知道目前更新或寫入資料是哪個服務。

package pojo.web.signup.update;

/**
 * 更新類型種類
 */
public class UpdateType {
  /** 更新會員檔案 */
  public final static String updateMemberProfile = "updateMemberProfile";
}

app.services.WebService.java
實作編輯會員明細相關服務。

...
  /** 檢查使用者手機是否重覆 */
  public boolean checkMemberDetailByCellphone(@Param("cellphone") String cellphone);

  /** 用手機號碼 尋找會員明細*/
  public MemberDetail findMemberDetailByMemberNo(@Param("memberNo") String memberNo);

  /** 更新使用者的使用者名稱 */
  public int updateMemberUsername(@Param("memberNo") String memberNo, @Param("newUsername") String newUsername);

  /** 寫入或更新memberDetail資料 */
  public int genMemberDetail(@Param("data") MemberDetail memberDetail);

  /** 寫入memberDetailLog資料 */
  public int genMemberDetailChangeLog(@Param("data") MemberDetail memberDetail);

...

app.services.Impl.WebServiceImpl.java
實作WebService內的方法。

...
  @Override
  public boolean checkMemberDetailByCellphone(@Param("cellphone") String cellphone ){
    return this.webService.checkMemberDetailByCellphone(cellphone);
  }

  @Override
  public MemberDetail findMemberDetailByMemberNo(@Param("memberNo") String memberNo ){
    return this.webService.findMemberDetailByMemberNo(memberNo);
  }

  @Override
  public int updateMemberUsername(@Param("memberNo") String memberNo, @Param("newUsername") String newUsername){
    return this.webService.updateMemberUsername(memberNo , newUsername);
  }

  @Override
  public int genMemberDetail(@Param("data") MemberDetail memberDetail){
    return this.webService.genMemberDetail(memberDetail);
  }

  @Override
  public int genMemberDetailChangeLog(@Param("data") MemberDetail memberDetail){
    return this.webService.genMemberDetailChangeLog(memberDetail);
  }
...

conf.services.WebService.xml

編輯會員明細相關寫入與查詢SQL。

    <!-- 檢查是否有重覆的手機號碼-->
    <select id="checkMemberDetailByCellphone" parameterType="Map" resultType="boolean">
        SELECT CASE WHEN EXISTS (SELECT 1 FROM member_detail de WHERE de.cellphone=#{cellphone})
               THEN 1 ELSE 0 END isUsedCellphone
        FROM DUAL
    </select>


    <!-- 根據手機號碼查詢會員明細資料 -->
    <select id="findMemberDetailByMemberNo" parameterType="String" resultType="pojo.web.MemberDetail">
        SELECT * FROM member_detail WHERE memberNo = #{memberNo}
    </select>    


    <!--  更新會員使用者名稱 -->
    <update id="updateMemberUsername">
        UPDATE member_main SET username = #{newUsername} , modifyDate = DATE_FORMAT(NOW(), '%Y%m%d%H%i%s') WHERE memberNo = #{memberNo}
    </update>


    <!-- 新增會員明細或更新 -->
    <insert id="genMemberDetail" parameterType="pojo.web.MemberDetail">
        insert into
        member_detail
        (memberNo , nickname , birthday , cellphone , headerPicLink , createDate , modifyDate)
        values
        ( 
            #{data.memberNo} , 
            #{data.nickname} ,
            #{data.birthday} ,
            #{data.cellphone} ,
            #{data.headerPicLink} ,
            DATE_FORMAT(NOW(), '%Y%m%d%H%i%s') ,
            DATE_FORMAT(NOW(), '%Y%m%d%H%i%s') 
        ) ON DUPLICATE KEY UPDATE 
        memberNo         = memberNo ,
        nickname         = #{data.nickname} ,
        birthday         = #{data.birthday} ,
        cellphone         = #{data.cellphone} ,
        headerPicLink     = #{data.headerPicLink} ,
        createDate      = createDate ,
        modifyDate      = DATE_FORMAT(NOW(), '%Y%m%d%H%i%s')
    </insert>    


    <!-- 會員明細記錄檔 -->
    <insert id="genMemberDetailChangeLog" parameterType="pojo.web.MemberDetail">
        insert into
        member_detail_log(memberNo , nickname , birthday , cellphone , headerPicLink , createDate)
        values
        ( 
            #{data.memberNo} , 
            #{data.nickname} ,
            #{data.birthday} ,
            #{data.cellphone} ,
            #{data.headerPicLink} ,
            DATE_FORMAT(NOW(), '%Y%m%d%H%i%s')
        )
    </insert>

app.utils.enc.EncAndDeCodeTool.java
因應頁面都是使用ajax檢核欄位資訊,所以我們針對Query String傳入時,都進行URL與Base64的加密,到達檢查時才解密成原本的資料進行驗證。

package utils.enc;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Base64;

/**
 * <pre>
 *  加解密工具
 * </pre>
 */
public class EncAndDeCodeTool {


  /**
   * 傳入字串,會進行URL與Base64加密 
   */
  public String urlAndBase64Encode(String unencodeStr){
    return this.base64Encode(this.urlEncode(unencodeStr));
  }


  /**
   * 傳入加密過Base64與URL的字串,進行解密
   */
  public String urlAndBase64Decode(String encodeStr){
    return this.urlDecode(this.base64Decode(encodeStr));
  }


  public String urlEncode(String encodeStr){
    try {
      return URLEncoder.encode(encodeStr , "UTF-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return "";
  }


  public String base64Encode(String encodeStr){
    return new String (Base64.getEncoder().encode(encodeStr.getBytes()));
  }


  public String urlDecode(String decodeStr){
    try {
      return URLDecoder.decode(decodeStr , "UTF-8");
    } catch (UnsupportedEncodingException e) {
      e.printStackTrace();
    }
    return "";
  }


  public String base64Decode(String decodeStr){
    return new String (Base64.getDecoder().decode(decodeStr.getBytes()));
  }


}

app.utils.http.HttpHelper.java
我們的圖片檢核,因為全都改用後端檢查,我們需要寫一個服務去檢視使用者填寫的頭像網址,確認它是圖片。

package utils.http;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ExecutionException;

import play.libs.ws.*;

/**
 * <pre> 
 *  Http 工具
 * </pre>
 */
public class HttpHelper {

  private WSClient ws ;

  public HttpHelper(WSClient ws){
    this.ws = ws;
  }

  /**
   * <pre> 
   *  檢查是否是圖片
   * </pre>
   */
  public boolean checkImgUrl(String url) {
    WSResponse response = null;
    int responseStatus = 0;
    boolean isImg = false;
    String contentType = "";
    try {

      String regex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";
      // 檢驗是否是網址,才執行檢查
      if(url.matches(regex)){

        // 設定要請求的資訊
        WSRequest request = ws.url(url);
        request.setRequestTimeout(10000);
        CompletionStage<WSResponse> responsePromise = request.get();

        if (responsePromise != null) {
          // 取得呼叫完的結果
          CompletableFuture<WSResponse> future = responsePromise.toCompletableFuture();
          response = future.get();
          responseStatus = response.getStatus(); // Http回覆碼
          contentType = response.getHeader("Content-Type");

          if( contentType == null || "".equals(contentType) || 
              contentType.indexOf("image") == -1 || responseStatus != 200){
            isImg = false;
          } else {
            isImg = true;
          }
        } else {
          isImg = false;
        }
      } else {
        isImg = false;
      }

    } catch (InterruptedException e) {
      e.printStackTrace();
    } catch (ExecutionException e) {
      e.printStackTrace();
    }
    play.Logger.info("isImg = " + isImg + " , url = " + url + " , Header Content-Type = " + contentType);
    return isImg;
  }

}

app.utils.signup.Utils_Signup.java
這個類別主要用途是,使用者編輯會員資料時,需要的欄位檢核與驗證,確認使用者填入的資料是正確的,以及會員相關資料的轉換。

  // 產生會員資料
  public MemberProfile genMemberProfile(Member member, MemberDetail memberDetail) {
    MemberProfile profile = new MemberProfile();
    profile.setUsername(member.getUsername()!=null && !"".equals(member.getUsername()) ? member.getUsername() : "");
    if(memberDetail != null){
      profile.setHeaderPicLink(memberDetail.getHeaderPicLink()!=null && !"".equals(memberDetail.getHeaderPicLink()) ? memberDetail.getHeaderPicLink() : "");
      profile.setNickname(memberDetail.getNickname()!=null && !"".equals(memberDetail.getNickname()) ? memberDetail.getNickname() : "");
      profile.setCellphone(memberDetail.getCellphone()!=null && !"".equals(memberDetail.getCellphone()) ? memberDetail.getCellphone() : "");
      String birthday = "";
      if(memberDetail.getBirthday()!=null && !"".equals(memberDetail.getBirthday())){
        String year = memberDetail.getBirthday().substring(0, 4);
        String month = memberDetail.getBirthday().substring(4, 6);
        String day = memberDetail.getBirthday().substring(6, 8);
        birthday = year + "/" + month + "/" + day;
      }
      profile.setBirthday(birthday);
    }
    profile.setEditable(member.getMemberNo() == null || "".equals(member.getMemberNo()) ? false : true);
    profile.setSystemMessage(member.getMemberNo() == null || "".equals(member.getMemberNo()) ? UpdateMemberProfileStatus.SE1.statusDesc : "");
    return profile;
  }


  // 驗證頭像
  public VerificCheckMessage checkHeaderPicLink(String headerPicLink , String dbHeaderPicLink , boolean isImg) {

    VerificCheckMessage message = new VerificCheckMessage();

    message.setInputName("headerPicLink");

    String urlRegex = "^(https?|ftp|file)://[-a-zA-Z0-9+&@#/%?=~_|!:,.;]*[-a-zA-Z0-9+&@#/%=~_|]";

    if (headerPicLink == null || "".equals(headerPicLink)) {
      message.setStatus(HeaderPicLinkStatus.S201.status);
      message.setStatusDesc(HeaderPicLinkStatus.S201.statusDesc);
      message.setPass(HeaderPicLinkStatus.S201.pass);
    } else if (!headerPicLink.matches(urlRegex)) {
      message.setStatus(HeaderPicLinkStatus.S1.status);
      message.setStatusDesc(HeaderPicLinkStatus.S1.statusDesc);
      message.setPass(HeaderPicLinkStatus.S1.pass);
    } else if (!isImg) {
      message.setStatus(HeaderPicLinkStatus.S2.status);
      message.setStatusDesc(HeaderPicLinkStatus.S2.statusDesc);
      message.setPass(HeaderPicLinkStatus.S2.pass);
    } else if (headerPicLink.equals(dbHeaderPicLink)) {
      message.setStatus(HeaderPicLinkStatus.S202.status);
      message.setStatusDesc(HeaderPicLinkStatus.S202.statusDesc);
      message.setPass(HeaderPicLinkStatus.S202.pass);
    } else {
      message.setStatus(HeaderPicLinkStatus.S200.status);
      message.setStatusDesc(HeaderPicLinkStatus.S200.statusDesc);
      message.setPass(HeaderPicLinkStatus.S200.pass);
    }

    play.Logger.info("checkHeaderPicLink = " + Json.toJson(message));

    return message;
  }


  // 驗證生日
  public VerificCheckMessage checkBirthday(String birthday, String dbBirthday) {
    VerificCheckMessage message = new VerificCheckMessage();

    message.setInputName("birthday");

    String birthDayRegex = "(((19|20)([2468][048]|[13579][26]|0[48])|2000)[/-]02[/-]29|((19|20)[0-9]{2}[/-](0[4678]|1[02])"+
                           "[/-](0[1-9]|[12][0-9]|30)|(19|20)[0-9]{2}[/-](0[1359]|11)[/-](0[1-9]|[12][0-9]|3[01])|(19|20)"+
                           "[0-9]{2}[/-]02[/-](0[1-9]|1[0-9]|2[0-8])))";

    if (birthday == null || "".equals(birthday)) {
      message.setStatus(BirthDayStatus.S201.status);
      message.setStatusDesc(BirthDayStatus.S201.statusDesc);
      message.setPass(BirthDayStatus.S201.pass);
    } else if (!birthday.matches(birthDayRegex)) {
      message.setStatus(BirthDayStatus.S1.status);
      message.setStatusDesc(BirthDayStatus.S1.statusDesc);
      message.setPass(BirthDayStatus.S1.pass);
    } else if (birthday.replaceAll("/", "").equals(dbBirthday)) {
      message.setStatus(BirthDayStatus.S202.status);
      message.setStatusDesc(BirthDayStatus.S202.statusDesc);
      message.setPass(BirthDayStatus.S202.pass);
    } else {
      // ex : 2017/03/01 => {2017,03,01}
      String[] birthdayArray = birthday.split("/");
      Calendar now = Calendar.getInstance();
      Calendar memberbirthDay = (Calendar) now.clone();

      memberbirthDay.set(Integer.parseInt(birthdayArray[0]), 
                         Integer.parseInt(birthdayArray[1])-1, // 0~11月
                         Integer.parseInt(birthdayArray[2]));

      if(memberbirthDay.getTime().getTime() > now.getTime().getTime()){
        message.setStatus(BirthDayStatus.S2.status);
        message.setStatusDesc(BirthDayStatus.S2.statusDesc);
        message.setPass(BirthDayStatus.S2.pass);
      } else {
        message.setStatus(BirthDayStatus.S200.status);
        message.setStatusDesc(BirthDayStatus.S200.statusDesc);
        message.setPass(BirthDayStatus.S200.pass);
      }
    }

    play.Logger.info("checkBirthday = " + Json.toJson(message));

    return message;
  }


  // 驗證使用者名稱 
  public VerificCheckMessage checkEditUsername(String username, String dbUsername,
      boolean isUsedUsername) {

    VerificCheckMessage message = new VerificCheckMessage();

    message.setInputName("username");

    String usernameRegex = "^[a-zA-Z]{4,15}$";

    if ("".equals(username) || username == null) {
      message.setStatus(UsernameStatus.S1.status);
      message.setStatusDesc(UsernameStatus.S1.statusDesc);
      message.setPass(UsernameStatus.S1.pass);
    } else if (username.equals(dbUsername)) {
      message.setStatus(UsernameStatus.S201.status);
      message.setStatusDesc(UsernameStatus.S201.statusDesc);
      message.setPass(UsernameStatus.S201.pass);
    } else if (!username.matches(usernameRegex)) {
      message.setStatus(UsernameStatus.S2.status);
      message.setStatusDesc(UsernameStatus.S2.statusDesc);
      message.setPass(UsernameStatus.S2.pass);
    } else if (isUsedUsername) {
      message.setStatus(UsernameStatus.S3.status);
      message.setStatusDesc(UsernameStatus.S3.statusDesc);
      message.setPass(UsernameStatus.S3.pass);
    } else {
      message.setStatus(UsernameStatus.S200.status);
      message.setStatusDesc(UsernameStatus.S200.statusDesc);
      message.setPass(UsernameStatus.S200.pass);
    }

    play.Logger.info("checkEditUsername = " + Json.toJson(message));

    return message;
  }


  // 驗證暱稱
  public VerificCheckMessage checkNickname(String nickname , String dbNickname) {
    VerificCheckMessage message = new VerificCheckMessage();

    message.setInputName("nickname");

    String nicknameRegex =
        ".*[`~!@#$%^&*()+=|{}':;',\\[\\].<>/?~!@#¥%……&*()——+|{}【】『;:」「』。,、?\\\\]+.*";

    if (nickname == null || "".equals(nickname)) {
      message.setStatus(NicknameStatus.S201.status);
      message.setStatusDesc(NicknameStatus.S201.statusDesc);
      message.setPass(NicknameStatus.S201.pass);
    } else if (nickname.length() < 1 || nickname.length() > 15) {
      message.setStatus(NicknameStatus.S1.status);
      message.setStatusDesc(NicknameStatus.S1.statusDesc);
      message.setPass(NicknameStatus.S1.pass);
    } else if (nickname.matches(nicknameRegex)) {
      message.setStatus(NicknameStatus.S2.status);
      message.setStatusDesc(NicknameStatus.S2.statusDesc);
      message.setPass(NicknameStatus.S2.pass);
    } else if (nickname.equals(dbNickname)){
      message.setStatus(NicknameStatus.S202.status);
      message.setStatusDesc(NicknameStatus.S202.statusDesc);
      message.setPass(NicknameStatus.S202.pass);
    } else {
      message.setStatus(NicknameStatus.S200.status);
      message.setStatusDesc(NicknameStatus.S200.statusDesc);
      message.setPass(NicknameStatus.S200.pass);
    }

    play.Logger.info("checkNickname = " + Json.toJson(message));

    return message;
  }


  // 驗證手機號碼
  public VerificCheckMessage checkCellphone(String cellphone, String dbCellphone,
      boolean isUsedCellphone) {

    VerificCheckMessage message = new VerificCheckMessage();

    message.setInputName("cellphone");

    String cellphoneRegex = "[0-9]{4}[0-9]{6}";

    if (cellphone == null || "".equals(cellphone)) {
      message.setStatus(CellphoneStatus.S201.status);
      message.setStatusDesc(CellphoneStatus.S201.statusDesc);
      message.setPass(CellphoneStatus.S201.pass);
    } else if (cellphone.equals(dbCellphone)){
      message.setStatus(CellphoneStatus.S202.status);
      message.setStatusDesc(CellphoneStatus.S202.statusDesc);
      message.setPass(CellphoneStatus.S202.pass);
    } else if (!cellphone.matches(cellphoneRegex)) {
      message.setStatus(CellphoneStatus.S1.status);
      message.setStatusDesc(CellphoneStatus.S1.statusDesc);
      message.setPass(CellphoneStatus.S1.pass);
    } else if (isUsedCellphone) {
      message.setStatus(CellphoneStatus.S2.status);
      message.setStatusDesc(CellphoneStatus.S2.statusDesc);
      message.setPass(CellphoneStatus.S2.pass);
    } else {
      message.setStatus(CellphoneStatus.S200.status);
      message.setStatusDesc(CellphoneStatus.S200.statusDesc);
      message.setPass(CellphoneStatus.S200.pass);
    }

    play.Logger.info("checkCellphone = " + Json.toJson(message));

    return message;

  }


  /**
   * <pre>
   * 傳入頁面會員明細資料
   * 
   * </pre>
   */
  public Map<String , VerificCheckMessage> checkMemberProfile(MemberProfile memberProfile ,Member member , MemberDetail memberDetail, 
                                                              boolean isImg , boolean isUsedUsername , boolean isUsedCellphone ) {

    String dbUsername =  member.getUsername();
    String dbHeaderPicLink = memberDetail != null ? memberDetail.getHeaderPicLink() : "";
    String dbBirthday = memberDetail != null ? memberDetail.getBirthday() : "";
    String dbCellphone = memberDetail != null ? memberDetail.getCellphone() : "" ;
    String dbNickname = memberDetail != null ? memberDetail.getNickname() : "";

    Map<String , VerificCheckMessage> results = new HashMap<String , VerificCheckMessage>();
    results.put("headerPicLink", checkHeaderPicLink(memberProfile.getHeaderPicLink() , dbHeaderPicLink , isImg));
    results.put("nickname", checkNickname(memberProfile.getNickname() , dbNickname));
    results.put("username", checkEditUsername(memberProfile.getUsername() ,  dbUsername , isUsedUsername));
    results.put("birthday", checkBirthday(memberProfile.getBirthday() , dbBirthday));
    results.put("cellphone", checkCellphone(memberProfile.getCellphone() , dbCellphone , isUsedCellphone));
    return results;
  }


  /**
   * <pre>
   * 整理會員明細資料
   * </pre>
   */
  public MemberDetail genMemberDetail(String memberNo, MemberProfile memberProfile) {
    MemberDetail detail = new MemberDetail();
    detail.setMemberNo(memberNo);
    // 生日:2017/03/01 => 20170301
    detail.setBirthday(memberProfile.getBirthday().replaceAll("/", ""));
    detail.setCellphone(memberProfile.getCellphone());
    detail.setHeaderPicLink(memberProfile.getHeaderPicLink());
    detail.setNickname(memberProfile.getNickname());
    return detail;
  }

app.controllers.WebController.java
前面的類別準備,已經可以架構出後端需要的會員資料的檢核以及寫入,接下來就是撰寫主要每個欄位的流程與實作,會根據欄位的不同,會撈取會員資料或會員明細資料,以及前端所輸入的欄位,送的Utils_Signup進行欄位驗證,檢核完畢之後,會回傳Json格式,讓前端頁面知道該欄位的狀態,是否可以進行後續處理。

  /**
   * 進入修改會員個人資料頁面
   */
  public Result editProfile(){
    return ok(editProfile.render());
  }


  /**
   * 即時載入會員明細個人資料 
   */
  public Result ajaxLoadMemberProfile(){
    Utils_Session utilSsession = new Utils_Session();
    MemberProfile memberProfile = new MemberProfile();
    try{
      String memberNo = utilSsession.getUserNo();
      Member member = webService.findMemberByMemberNo(memberNo);
      MemberDetail memberDetail = webService.findMemberDetailByMemberNo(memberNo);
      memberProfile = new Utils_Signup().genMemberProfile(member , memberDetail);
    } catch (Exception e) {
      e.printStackTrace();
    }
    Logger.info("ajaxLoadMemberProfile = " + Json.toJson(memberProfile));
    return ok(Json.toJson(memberProfile));
  }


  /**
   * <pre>
   * 修改會員個人資料動作 
   * 
   * Step 1 : 確認使用者填入的資料
   * Step 2 : 確認無誤,寫入使用者資料
   * Step 3 : 確認更新狀態,回傳更新寫入訊息
   * 
   * </pre>
   */
  public Result doEditProfile(){
    Logger.info("start doEditProfile");
    Date startTime = new Date();
    boolean isAllPass = false;
    String updateType = "";
    String status = "";
    String statusDesc = "";
    String costTime = "";
    String memberNo = "";
    boolean update = false;
    Map<String , VerificCheckMessage> verificResults = null;
    Utils_Session utilSsession = new Utils_Session();
    UpdateMessage updateMessage = new UpdateMessage();
    Utils_Signup utilsSignup = new Utils_Signup() ;
    try{

      // Step 1
      MemberProfile memberProfile = formFactory.form(MemberProfile.class).bindFromRequest().get();
      memberNo = utilSsession.getUserNo();
      Member member = webService.findMemberByMemberNo(memberNo);
      MemberDetail memberDetail = webService.findMemberDetailByMemberNo(memberNo);
      boolean isImg = new HttpHelper(ws).checkImgUrl(memberProfile.getHeaderPicLink());
      boolean isUsedUsername = webService.checkMemberByUsername(memberProfile.getUsername());
      boolean isUsedCellphone = webService.checkMemberDetailByCellphone(memberProfile.getCellphone());
      verificResults = utilsSignup.checkMemberProfile(memberProfile , member , memberDetail ,
                                                      isImg , isUsedUsername , isUsedCellphone );

      Logger.info("Step 1 檢驗結果 : " + Json.toJson(verificResults));

      // Step 2
      isAllPass = false;
      for(String key : verificResults.keySet()){
        isAllPass = verificResults.get(key).isPass();
        if(!isAllPass){
          break;
        }
      }
      Logger.info("Step 2 全部欄位檢查後,是否允許可以更新與寫入會員資料 : " + isAllPass);


      // Step 3
      if(isAllPass){
        // 寫入Member記錄檔,與更新使用者名稱
        boolean insertMemberLogOk = webService.genMemberChangeLog(member) > 0 ? true : false;
        boolean updateUseenameOk = webService.updateMemberUsername(memberNo , memberProfile.getUsername()) > 0 ? true : false ;

        // 寫入MemberDetail與記錄檔
        MemberDetail newMemberDetail = utilsSignup.genMemberDetail(memberNo , memberProfile);
        boolean updateMemberDeatilOk = webService.genMemberDetail(newMemberDetail) > 0 ? true : false;
        boolean insertMemberDetailLogOk = webService.genMemberDetailChangeLog(newMemberDetail) > 0 ? true : false;

        Logger.info("Step 3 更新或寫入資料是否成功 : updateUseenameOk(更新使用者名稱) : " + updateUseenameOk + 
                    " , insertMemberLogOk(寫入會員log檔) : " + insertMemberLogOk +
                    " , updateMemberDeatilOk(寫入或更新會員明細) : " + updateMemberDeatilOk +
                    " , insertMemberDetailLogOk(寫入會員明細log檔) : " + insertMemberDetailLogOk);

        if(insertMemberLogOk && updateUseenameOk && updateMemberDeatilOk && insertMemberDetailLogOk){
          status = UpdateMemberProfileStatus.S200.status;
          statusDesc = UpdateMemberProfileStatus.S200.statusDesc;
          update = UpdateMemberProfileStatus.S200.update;
        } else {
          status = UpdateMemberProfileStatus.SE1.status;
          statusDesc = UpdateMemberProfileStatus.SE1.statusDesc;
          update = UpdateMemberProfileStatus.SE1.update;
        }
      } else {
        status = UpdateMemberProfileStatus.E1.status;
        statusDesc = UpdateMemberProfileStatus.E1.statusDesc;
        update = UpdateMemberProfileStatus.E1.update;
      }

    } catch (Exception e){
      e.printStackTrace();
      status = UpdateMemberProfileStatus.SE1.status;
      statusDesc = UpdateMemberProfileStatus.SE1.statusDesc;
      update = UpdateMemberProfileStatus.SE1.update;
    } finally {
      costTime = (new Date().getTime() - startTime.getTime()) + " ms";
      updateType = UpdateType.updateMemberProfile;
      updateMessage.setUpdateType(updateType);
      updateMessage.setStatus(status);
      updateMessage.setStatusDesc(statusDesc);
      updateMessage.setUpdate(update);
      updateMessage.setCostTime(costTime);
      updateMessage.setVerificResults(verificResults);

    }
    Logger.info("finish doEditProfile = " + Json.toJson(updateMessage));
    return ok(Json.toJson(updateMessage));
  } 

  // 相依性注入 play.libs.ws.WSClient,可以用來呼叫別人寫好的Http服務
  @Inject
  WSClient ws;


  /**
   * 即時檢核圖片 
   */
  public Result ajaxCheckHeaderPicLink(){
    String encodeUrl = "";
    String headerPicLink = "";
    String dbHeaderPicLink = "";
    boolean isImg = false;
    Utils_Session utilSsession = new Utils_Session();
    EncAndDeCodeTool tool = new EncAndDeCodeTool();
    try{
      HttpHelper httpHelper = new HttpHelper(ws);
      encodeUrl = request().getQueryString("headerPicLink");
      headerPicLink = tool.urlAndBase64Decode(encodeUrl);
      isImg = httpHelper.checkImgUrl(headerPicLink);
      String memberNo = utilSsession.getUserNo();
      MemberDetail detail = webService.findMemberDetailByMemberNo(memberNo);
      dbHeaderPicLink = detail != null ? detail.getHeaderPicLink() : "";
    } catch (Exception e){
      e.printStackTrace();
    }
    VerificCheckMessage verificInfo = new Utils_Signup().checkHeaderPicLink(headerPicLink , dbHeaderPicLink, isImg);
    return ok(Json.toJson(verificInfo));
  }

  /**
   * 即時檢核使用者生日 
   */
  public Result ajaxCheckBirthday(){
    String encBirthday = "";
    String birthday = "";
    String dbBirthday = "";
    Utils_Session utilSsession = new Utils_Session();
    EncAndDeCodeTool tool = new EncAndDeCodeTool();
    try{
      encBirthday = request().getQueryString("birthday");
      birthday = tool.urlAndBase64Decode(encBirthday);
      String memberNo = utilSsession.getUserNo();
      MemberDetail detail = webService.findMemberDetailByMemberNo(memberNo);
      dbBirthday = detail != null ? detail.getBirthday() : "";
    } catch (Exception e){
      e.printStackTrace();
    }
    VerificCheckMessage verificInfo = new Utils_Signup().checkBirthday(birthday, dbBirthday);
    return ok(Json.toJson(verificInfo));
  }

  /**
   * 即時檢核使用者名稱 
   */
  public Result ajaxCheckUsername(){
    String encUsername = "";
    String username = "";
    String dbUsername = "";
    boolean isUsedUsername = true;
    Utils_Session utilSsession = new Utils_Session();
    EncAndDeCodeTool tool = new EncAndDeCodeTool();
    try {
      encUsername = request().getQueryString("username");
      username = tool.urlAndBase64Decode(encUsername);
      isUsedUsername = webService.checkMemberByUsername(username);
      dbUsername = webService.findMemberByMemberNo(utilSsession.getUserNo()).getUsername();
    } catch (Exception e){
      e.printStackTrace();
    }

    VerificCheckMessage verificInfo = new Utils_Signup().checkEditUsername(username , dbUsername, isUsedUsername);
    return ok(Json.toJson(verificInfo));
  }


  /**
   * 即時檢核暱稱 
   */
  public Result ajaxCheckNickname(){
    String encNickname = "";
    String dbNickname = "";
    String nickname = "";
    Utils_Session utilSsession = new Utils_Session();
    EncAndDeCodeTool tool = new EncAndDeCodeTool();
    try {
      encNickname = request().getQueryString("nickname");
      String memberNo = utilSsession.getUserNo();
      nickname = tool.urlAndBase64Decode(encNickname);
      MemberDetail detail = webService.findMemberDetailByMemberNo(memberNo);
      dbNickname = detail != null ? detail.getNickname() : "";
    } catch (Exception e){
      e.printStackTrace();
    }

    VerificCheckMessage verificInfo = new Utils_Signup().checkNickname(nickname , dbNickname);
    return ok(Json.toJson(verificInfo));
  }


  /**
   * 即時檢核手機號碼
   */
  public Result ajaxCheckCellphone(){
    String encCellphone = "";
    String cellphone = "";
    String dbCellphone = "";
    boolean isUsedCellphone = true;
    Utils_Session utilSsession = new Utils_Session();
    EncAndDeCodeTool tool = new EncAndDeCodeTool();
    try {
      encCellphone = request().getQueryString("cellphone");
      cellphone = tool.urlAndBase64Decode(encCellphone);
      String memberNo = utilSsession.getUserNo();
      isUsedCellphone = webService.checkMemberDetailByCellphone(cellphone);
      MemberDetail detail = webService.findMemberDetailByMemberNo(memberNo);
      dbCellphone = detail != null ? detail.getCellphone() : "";
    } catch (Exception e){
      e.printStackTrace();
    }

    VerificCheckMessage verificInfo = new Utils_Signup().checkCellphone(cellphone, dbCellphone , isUsedCellphone);
    return ok(Json.toJson(verificInfo));
  }

conf.routes

當我們完成主要後端功能,後端服務最後一個任務是,把服務寫到routes上,讓前端頁面可以呼叫到WebController裡相關的服務。

# http://127.0.0.1:9000/web/editProfile
GET        /web/editProfile                    controllers.WebController.editProfile()

# http://127.0.0.1:9000/web/doEditProfile
POST    /web/editProfile                    controllers.WebController.doEditProfile()

# http://127.0.0.1:9000/web/ajaxLoadMemberProfile
GET        /web/ajaxLoadMemberProfile            controllers.WebController.ajaxLoadMemberProfile()

# http://127.0.0.1:9000/web/ajaxCheckHeaderPicLink
GET        /web/ajaxCheckHeaderPicLink            controllers.WebController.ajaxCheckHeaderPicLink()

# http://127.0.0.1:9000/web/ajaxCheckBirthday
GET        /web/ajaxCheckBirthday                controllers.WebController.ajaxCheckBirthday()

# http://127.0.0.1:9000/web/ajaxCheckUsername
GET        /web/ajaxCheckUsername                controllers.WebController.ajaxCheckUsername()

# http://127.0.0.1:9000/web/ajaxCheckNickname
GET        /web/ajaxCheckNickame                controllers.WebController.ajaxCheckNickname()

# http://127.0.0.1:9000/web/ajaxCheckCellphone
GET        /web/ajaxCheckCellphone                controllers.WebController.ajaxCheckCellphone()

results matching ""

    No results matching ""