単一のJavaアプリケーション - プロジェクトの戦闘(バックグラウンド) - アカウント管理の背景03 - 03.新しいアカウント

オリジナル住所:http://www.work100.net/training/monolithic-project-iot-cloud-admin-manager-add.html
その他のチュートリアル:ビーム雲-無料講座

新規アカウント

いいえ。 記事のセクション ビデオ
1 アウトライン -
2 バックエンドのコードの実装 -
3 フロントページを達成 -
4 テストと認定 -
5 フォームタグライブラリを使用します -
6 使用フォーム検証 -
7 ソースコードの例 -

上記をご参照ください章节导航読み取るために

1.概要

このセクションの実現新增账户次のように関数は、ページの効果は次のとおりです。

2.バックエンド・コードの実装

カップリングを減らすために、我々はあなたがすることを示唆している新增编辑查看機能は別に、一つの方法で混合されていないエンコードされました。

私たちは今、機能が比較的単純である証明が、実際のビジネス機能は、コードが混在一緒であれば、コードの複雑さは指数関数的に成長する、非常に複雑になります。

次に、我々は徐々に再構築されManagerControllerたクラスを。

GETメソッド

@RequestMapping(value = "add", method = RequestMethod.GET)
public String add() {
    return "auth/manager_add";
}

POSTメソッド

@RequestMapping(value = "add", method = RequestMethod.POST)
public String add(AuthManager authManager, Model model, RedirectAttributes redirectAttributes) {
    // 表单验证
    if (StringUtils.isBlank(authManager.getUserName())) {
        model.addAttribute("baseResult", BaseResult.fail("用户名不能空"));
        model.addAttribute("authManager", authManager);
        return "auth/manager_add";
    }
    if (authManager.getUserName().length() < 4 || authManager.getUserName().length() > 20) {
        model.addAttribute("baseResult", BaseResult.fail("用户名不能小于4位且不能大于20位"));
        model.addAttribute("authManager", authManager);
        return "auth/manager_add";
    }
    if (StringUtils.isBlank(authManager.getPassword())) {
        model.addAttribute("baseResult", BaseResult.fail("密码不能空且不能少于"));
        model.addAttribute("authManager", authManager);
        return "auth/manager_add";
    }
    if (authManager.getPassword().length() < 6 || authManager.getUserName().length() > 20) {
        model.addAttribute("baseResult", BaseResult.fail("密码不能小于6个位且不能大于20位"));
        model.addAttribute("authManager", authManager);
        return "auth/manager_add";
    }
    if (StringUtils.isBlank(authManager.getRoles())) {
        model.addAttribute("baseResult", BaseResult.fail("角色不能空"));
        model.addAttribute("authManager", authManager);
        return "auth/manager_add";
    }

    // 新增处理
    BaseResult baseResult = authManagerService.insert(authManager);
    if (baseResult.getStatus() == HttpUtils.HTTP_STATUS_CODE_OK) {
        redirectAttributes.addFlashAttribute("baseResult", baseResult);
        return "redirect:/auth/manager/list";
    } else {
        model.addAttribute("baseResult", baseResult);
        return "auth/manager_add";
    }
}

説明

  • バックエンドは、データのセキュリティを確保するために、フロントエンドの正当性を検証するために、データを提出しなければなりません

  • この方法を使用BaseResultし、HttpUtils2つのクラスは、以下のことが紹介されました

BaseResultクラス

より便利な演算結果は、フロントページに送信されるためには、我々は一般的な紹介BaseResult、次のように、クラスを:

package net.work100.training.stage2.iot.cloud.commons.dto;

import net.work100.training.stage2.iot.cloud.commons.utils.HttpUtils;

import java.io.Serializable;

/**
 * <p>Title: BaseResult</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-03-04 11:02
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-03-04   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public class BaseResult implements Serializable {
    private int status;
    private String message;


    public static BaseResult success() {
        return createResult(HttpUtils.HTTP_STATUS_CODE_OK, "成功");
    }

    public static BaseResult success(String message) {
        return createResult(HttpUtils.HTTP_STATUS_CODE_OK, message);
    }

    public static BaseResult fail() {
        return createResult(HttpUtils.HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR, "失败");
    }

    public static BaseResult fail(String message) {
        return createResult(HttpUtils.HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR, message);
    }

    public static BaseResult fail(int status, String message) {
        return createResult(status, message);
    }

    public int getStatus() {
        return status;
    }

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

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    private static BaseResult createResult(int status, String message) {
        BaseResult baseResult = new BaseResult();
        baseResult.setStatus(status);
        baseResult.setMessage(message);
        return baseResult;
    }
}

クラスファイルの場所iot-cloud-commonsプロジェクト内のnet.work100.training.stage2.iot.cloud.commons.dtoクラスパッケージの下。

HttpUtilsクラス

するにはBaseResult、一般的なクラス構成されたステータスコードを返しHttpUtils、次のように、:

package net.work100.training.stage2.iot.cloud.commons.utils;

/**
 * <p>Title: Http状态码</p>
 * <p>Description: </p>
 * <p>Url: http://www.work100.net/training/monolithic-project-iot-cloud-admin.html</p>
 *
 * @author liuxiaojun
 * @date 2019-07-14 20:51
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2019-07-14   liuxiaojun     初始创建
 * -----------------------------------------------
 */
public class HttpUtils {

    public static final int HTTP_STATUS_CODE_CONTINUE = 100;
    public static final int HTTP_STATUS_CODE_SWITCHING_PROTOCOLS = 101;
    public static final int HTTP_STATUS_CODE_OK = 200;
    public static final int HTTP_STATUS_CODE_CREATED = 201;
    public static final int HTTP_STATUS_CODE_ACCEPTED = 202;
    public static final int HTTP_STATUS_CODE_NON_AUTHORITATIVE_INFORMATION = 203;
    public static final int HTTP_STATUS_CODE_NO_CONTENT = 204;
    public static final int HTTP_STATUS_CODE_RESET_CONTENT = 205;
    public static final int HTTP_STATUS_CODE_PARTIAL_CONTENT = 206;
    public static final int HTTP_STATUS_CODE_MULTIPLE_CHOICES = 300;
    public static final int HTTP_STATUS_CODE_MOVED_PERMANENTLY = 301;
    public static final int HTTP_STATUS_CODE_MOVED_TEMPORARILY = 302;
    public static final int HTTP_STATUS_CODE_FOUND = 302;
    public static final int HTTP_STATUS_CODE_SEE_OTHER = 303;
    public static final int HTTP_STATUS_CODE_NOT_MODIFIED = 304;
    public static final int HTTP_STATUS_CODE_USE_PROXY = 305;
    public static final int HTTP_STATUS_CODE_TEMPORARY_REDIRECT = 307;
    public static final int HTTP_STATUS_CODE_BAD_REQUEST = 400;
    public static final int HTTP_STATUS_CODE_UNAUTHORIZED = 401;
    public static final int HTTP_STATUS_CODE_PAYMENT_REQUIRED = 402;
    public static final int HTTP_STATUS_CODE_FORBIDDEN = 403;
    public static final int HTTP_STATUS_CODE_NOT_FOUND = 404;
    public static final int HTTP_STATUS_CODE_METHOD_NOT_ALLOWED = 405;
    public static final int HTTP_STATUS_CODE_NOT_ACCEPTABLE = 406;
    public static final int HTTP_STATUS_CODE_PROXY_AUTHENTICATION_REQUIRED = 407;
    public static final int HTTP_STATUS_CODE_REQUEST_TIMEOUT = 408;
    public static final int HTTP_STATUS_CODE_CONFLICT = 409;
    public static final int HTTP_STATUS_CODE_GONE = 410;
    public static final int HTTP_STATUS_CODE_LENGTH_REQUIRED = 411;
    public static final int HTTP_STATUS_CODE_PRECONDITION_FAILED = 412;
    public static final int HTTP_STATUS_CODE_REQUEST_ENTITY_TOO_LARGE = 413;
    public static final int HTTP_STATUS_CODE_REQUEST_URI_TOO_LONG = 414;
    public static final int HTTP_STATUS_CODE_UNSUPPORTED_MEDIA_TYPE = 415;
    public static final int HTTP_STATUS_CODE_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
    public static final int HTTP_STATUS_CODE_EXPECTATION_FAILED = 417;
    public static final int HTTP_STATUS_CODE_INTERNAL_SERVER_ERROR = 500;
    public static final int HTTP_STATUS_CODE_NOT_IMPLEMENTED = 501;
    public static final int HTTP_STATUS_CODE_BAD_GATEWAY = 502;
    public static final int HTTP_STATUS_CODE_SERVICE_UNAVAILABLE = 503;
    public static final int HTTP_STATUS_CODE_GATEWAY_TIMEOUT = 504;
    public static final int HTTP_STATUS_CODE_HTTP_VERSION_NOT_SUPPORTED = 505;
}

クラスファイルの場所iot-cloud-commonsプロジェクト内のnet.work100.training.stage2.iot.cloud.commons.utilsクラスパッケージの下。

AuthManagerServiceサービス・インターフェース

復興AuthManagerServiceサービスインタフェースinsert次のコードのように:

/**
 * 新增
 *
 * @param authManager
 * @return
 */
BaseResult insert(AuthManager authManager);

AuthManagerServiceImplサービスの実装

再構成AuthManagerServiceImplサービスの実装insertは次のような方法では、コードは次のとおりです。

@Override
public BaseResult insert(AuthManager authManager) {
    if (authManagerDao.getByUserName(authManager.getUserName()) != null) {
        return BaseResult.fail("用户名已经存在");
    }
    try {
        // 生成 userKey
        authManager.setUserKey(generateUserKey(authManager.getUserName()));

        // 密码加密
        authManager.setPassword(EncryptionUtils.encryptPassword(EncryptionUtils.EncryptionType.MD5, authManager.getPassword()));
        authManager.setCreated(new Date());
        authManager.setUpdated(new Date());

        authManagerDao.insert(authManager);
        return BaseResult.success("新增账户成功");
    } catch (Exception ex) {
        return BaseResult.fail("未知错误");
    }
}

新しいgenerateUserKey方法は、達成するためにuserKey、次のように、生成ロジックを:

/**
 * 生成 userKey
 *
 * @param userName 用户名
 * @return
 */
private String generateUserKey(String userName) {
    String strDate = DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss");
    String sourceUserKey = String.format("%s%s", userName.toLowerCase(), strDate);
    return EncryptionUtils.encryptText(EncryptionUtils.EncryptionType.MD5, sourceUserKey);
}

フロントページを達成3.

ビューファイルmanager_add.jsp

ではviews/auth/、ディレクトリの追加manager_add.jsp、次のようにビューファイルを、コードは次のとおりです。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html>
<head>
    <title>新增账户 - 后台账户 | IoT-Admin</title>
    <jsp:include page="../includes/resources_head.jsp" />
</head>
<body class="hold-transition sidebar-mini">
<div class="wrapper">

    <jsp:include page="../includes/layout_header.jsp" />

    <jsp:include page="../includes/layout_left.jsp" />

    <!-- Content Wrapper. Contains page content -->
    <div class="content-wrapper">
        <!-- Content Header (Page header) -->
        <div class="content-header">
            <div class="container-fluid">
                <div class="row mb-2">
                    <div class="col-sm-6">
                        <h1 class="m-0 text-dark">新增账户</h1>
                    </div><!-- /.col -->
                    <div class="col-sm-6">
                        <ol class="breadcrumb float-sm-right">
                            <li class="breadcrumb-item"><a href="#">后台账户</a></li>
                            <li class="breadcrumb-item active">新增账户</li>
                        </ol>
                    </div><!-- /.col -->
                </div><!-- /.row -->
            </div><!-- /.container-fluid -->
        </div>
        <!-- /.content-header -->

        <!-- Main content -->
        <div class="content">
            <div class="container-fluid">
                <div class="row">
                    <div class="col">
                        <div class="card card-gray">
                            <!-- /.card-header -->
                            <!-- form start -->
                            <form action="/auth/manager/add" method="post">
                                <div class="card-body">
                                    <div class="row">
                                        <div class="col-md-6">
                                            <div class="form-group">
                                                <label for="userName">用户名</label>
                                                <input type="text" class="form-control" id="userName" name="userName" placeholder="请输入用户名" value="${authManager.userName}">
                                            </div>
                                            <div class="form-group">
                                                <label for="password">密码</label>
                                                <input type="password" class="form-control" id="password" name="password" placeholder="请输入密码">
                                            </div>
                                            <div class="form-group">
                                                <label for="status">状态</label>
                                                <select class="form-control select2" style="width: 100%;" id="status" name="status">
                                                    <option value="0" selected="selected">未激活</option>
                                                    <option value="1">激活</option>
                                                    <option value="2">锁定</option>
                                                    <option value="3">删除</option>
                                                </select>
                                            </div>
                                        </div>
                                        <div class="col-md-6">
                                            <div class="form-group">
                                                <label for="roles">角色</label>
                                                <select class="select2" id="roles" name="roles" multiple="multiple" data-placeholder="请选择角色" style="width: 100%;">
                                                    <option value="admin" ${authManager.roles.contains("admin")?"selected":""}>admin</option>
                                                    <option value="editor" ${authManager.roles.contains("editor")?"selected":""}>editor</option>
                                                </select>
                                            </div>
                                            <div class="form-group">
                                                <label for="superuser">是否超级用户</label>
                                                <select class="form-control select2" id="superuser" name="superuser" style="width: 100%;">
                                                    <option value="0" selected="selected">否</option>
                                                    <option value="1">是</option>
                                                </select>
                                            </div>
                                        </div>
                                    </div>
                                </div>
                                <!-- /.card-body -->

                                <div class="card-footer">
                                    <button type="submit" class="btn btn-primary">保存</button>
                                    <a href="/auth/manager/list" type="button" class="btn btn-default">返回列表</a>
                                </div>
                            </form>
                        </div>
                        <!-- /.card -->
                    </div>
                </div>
            </div>
            <!-- /.container-fluid -->
        </div>
        <!-- /.content -->
    </div>
    <!-- /.content-wrapper -->

    <jsp:include page="../includes/layout_footer.jsp" />
</div>
<!-- ./wrapper -->
<jsp:include page="../includes/resources_body.jsp" />

<script>
$(function() {
    //Initialize Select2 Elements
    $('.select2').select2();

    //Initialize Select2 Elements
    $('.select2bs4').select2({
        theme: 'bootstrap4'
    });

    if (${baseResult.status != null && baseResult.status != 200}) {
        const Toast = Swal.mixin({
            toast: true,
            position: 'top',
            showConfirmButton: false,
            timer: 2000,
            timerProgressBar: true,
            onOpen: (toast) => {
                toast.addEventListener('mouseenter', Swal.stopTimer)
                toast.addEventListener('mouseleave', Swal.resumeTimer)
            }
        })

        Toast.fire({
            type: 'error',
            title: '${baseResult.message}'
        })
    }
})
</script>
</body>
</html>

依存スクリプトとコントロール

我々は段落追加したファイルの最後JSのスクリプトを:

次のコードは、できるようにすることですselect制御アプリケーションのBootstrap4スタイルを:

//Initialize Select2 Elements
$('.select2').select2();

//Initialize Select2 Elements
$('.select2bs4').select2({
    theme: 'bootstrap4'
});

次のコードは、メッセージアウトに演算結果がユーザにとってより親しみやすい表示することです:

if (${baseResult.status != null && baseResult.status != 200}) {
    const Toast = Swal.mixin({
        toast: true,
        position: 'top',
        showConfirmButton: false,
        timer: 2000,
        timerProgressBar: true,
        onOpen: (toast) => {
            toast.addEventListener('mouseenter', Swal.stopTimer)
            toast.addEventListener('mouseleave', Swal.resumeTimer)
        }
    })

    Toast.fire({
        type: 'error',
        title: '${baseResult.message}'
    })
}

ページで使用されるselectコントロールおよびプロンプトは消息、関連するプラグイン、プラグを依拠に依存するCSSJSしているresources_head.jsresources_body.js導入:

resources_head.js コードは以下の通りであります:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<!-- Font Awesome Icons -->
<link rel="stylesheet" href="/static/assets/plugins/fontawesome-free/css/all.min.css">

<!-- iCheck for checkboxes and radio inputs -->
<link rel="stylesheet" href="/static/assets/plugins/icheck-bootstrap/icheck-bootstrap.min.css">

<!-- Select2 -->
<link rel="stylesheet" href="/static/assets/plugins/select2/css/select2.min.css">
<link rel="stylesheet" href="/static/assets/plugins/select2-bootstrap4-theme/select2-bootstrap4.min.css">

<!-- SweetAlert2 -->
<link rel="stylesheet" href="/static/assets/plugins/sweetalert2/sweetalert2.min.css">

<!-- Theme style -->
<link rel="stylesheet" href="/static/assets/css/adminlte.min.css">
<link rel="icon" href="/static/assets/img/favicon.ico">

resources_body.js コードは以下の通りであります:

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!-- REQUIRED SCRIPTS -->

<!-- jQuery -->
<script src="/static/assets/plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap -->
<script src="/static/assets/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- Select2 -->
<script src="/static/assets/plugins/select2/js/select2.full.min.js"></script>

<!-- SweetAlert2 -->
<script src="/static/assets/plugins/sweetalert2/sweetalert2.min.js"></script>

<!-- AdminLTE -->
<script src="/static/assets/js/adminlte.js"></script>

ビューファイルmanager_list.jsp

ファイルを見るmanager_list.jspにはbody、スクリプトの追加メッセージプロンプトを終了:

<script>
$(function() {
    if (${baseResult.status != null && baseResult.status == 200}) {
        const Toast = Swal.mixin({
            toast: true,
            position: 'top',
            showConfirmButton: false,
            timer: 2000,
            timerProgressBar: true
        })

        Toast.fire({
            type: 'success',
            title: '${baseResult.message}'
        })
    }
})
</script>

4.テストを実行します

再起動のTomcatテスト新增账户機能は、以下のデータは、障害時の迅速な効果を検証します:

成功したアカウントを追加すると、リストが促さページと成功を向けるだろう。

5.フォームタグライブラリ

ページのビューの符号化を簡単にするために、私たちは「使用することができます-フォームタグライブラリのSpring MVCページビューの再構築に関する知識のセクション」を。

formタグライブラリの導入

manager_add.jsp導入部ビューページヘッダのformタグライブラリ、次のように

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>

formタグを使用します

変換form形式は、次の通り:

<form:form action="/auth/manager/add" method="post" modelAttribute="authManager">
    <div class="card-body">
        <div class="row">
            <div class="col-md-6">
                <div class="form-group">
                    <label for="userName">用户名</label>
                    <form:input path="userName" cssClass="form-control" placeholder="请输入用户名" />
                </div>
                <div class="form-group">
                    <label for="password">密码</label>
                    <form:password path="password" cssClass="form-control" placeholder="请输入密码" />
                </div>
                <div class="form-group">
                    <label for="status">状态</label>
                    <form:select path="status" cssClass="form-control select2" style="width: 100%;">
                        <option value="0" selected="selected">未激活</option>
                        <option value="1">激活</option>
                        <option value="2">锁定</option>
                        <option value="3">删除</option>
                    </form:select>
                </div>
            </div>
            <div class="col-md-6">
                <div class="form-group">
                    <label for="roles">角色</label>
                    <form:select path="roles" cssClass="select2" multiple="multiple" data-placeholder="请选择角色" style="width: 100%;">
                        <option value="admin" ${authManager.roles.contains("admin")?"selected":""}>admin</option>
                        <option value="editor" ${authManager.roles.contains("editor")?"selected":""}>editor</option>
                    </form:select>
                </div>
                <div class="form-group">
                    <label for="superuser">是否超级用户</label>
                    <form:select path="superuser" cssClass="form-control select2" style="width: 100%;">
                        <option value="0" selected="selected">否</option>
                        <option value="1">是</option>
                    </form:select>
                </div>
            </div>
        </div>
    </div>
    <!-- /.card-body -->

    <div class="card-footer">
        <button type="submit" class="btn btn-primary">保存</button>
        <a href="/auth/manager/list" type="button" class="btn btn-default">返回列表</a>
    </div>
</form:form>

変革のバックエンド・コード

再構成ManagerController制御GET方法

@RequestMapping(value = "add", method = RequestMethod.GET)
public String add(Model model) {
    AuthManager authManager = new AuthManager();
    model.addAttribute("authManager", authManager);
    return "auth/manager_add";
}

6.フォーム検証

jqueryの検証を導入

includes/resources_body.jsp文書導入jquery-validation次のようにプラグインに依存するコードです。

<!-- jquery-validation -->
<script src="/static/assets/plugins/jquery-validation/jquery.validate.min.js"></script>
<script src="/static/assets/plugins/jquery-validation/additional-methods.min.js"></script>
<script src="/static/assets/plugins/jquery-validation/localization/messages_zh.min.js"></script>

カスタムフォームID

フォームを定義したid次のように、:

<form:form action="/auth/manager/add" id="form" method="post" modelAttribute="authManager">

検証スクリプトを達成

ビューのページではmanager_add.jsp、ファイルbody末尾にスクリプト内で、次のコードを追加します。

$("#form").validate({
    rules: {
        userName: {
            required: true,
            minlength: 4,
            maxlength: 20
        },
        password: {
            required: true,
            minlength: 6,
            maxlength: 20
        },
        roles: {
            required: true,
            minlength: 1,
            maxlength: 3
        }
    },
    messages: {
        userName: {
            required: " 请输入用户名",
            minlength: " 用户名不能小于4位",
            maxlength: " 用户名不能大于于20位"
        },
        password: {
            required: " 请输入密码",
            minlength: " 密码不能小于6位",
            maxlength: " 密码不能大于于20位"
        },
        roles: {
            required: " 请选择角色",
            minlength: " 至少选择1个角色",
            maxlength: " 至多选择3个角色"
        }
    },
    errorElement: 'span',
    errorPlacement: function(error, element) {
        error.addClass('invalid-feedback');
        element.closest('.form-group').children('label').append(error);
    },
    highlight: function(element, errorClass, validClass) {
        $(element).addClass('is-invalid');
    },
    unhighlight: function(element, errorClass, validClass) {
        $(element).removeClass('is-invalid');
    }
});

次のようにフォームの検証結果は以下のとおりです。

実施例7ソース

ソースの例としては、以下のアドレスに管理されています:


前:アカウントリストショー

次へ:[アカウントの編集


あなたがコース内容に興味がある場合は、私たちの関心は、庭を掃除することができます公众号か、QQ群私たちのカリキュラムの更新をタイムリーに

おすすめ

転載: www.cnblogs.com/liuxiaojun/p/training-monolithic-project-iot-cloud-admin-manager-add.html