Джин (четыре): проверка отправки формы и привязка модели

Go Gin

Статья впервые опубликована вISLAND

В предыдущей главе была постепенно построена веб-страница Теперь мы начинаем постепенно улучшать функции на странице Первое, что нужно сделать, это функции входа и регистрации.

принять данные формы

HTML-элементы страницы регистрации подробно не прописаны, и можно напрямую ссылаться на конкретный код страницы.Githubкод выше.

Внешний вид страницы после завершения:

На странице регистрации есть три поля ввода, которыеemail ,passwordиpassword again.

Улучшить внутренний код Gin. мы вinitRouterсерединаuserGroupПри подготовке нового интерфейса.

		userRouter.POST("/register", handler.UserRegister)

После написания нового интерфейса начните писатьHandler.

func UserRegister(context *gin.Context) {
	email := context.PostForm("email")
	password := context.DefaultPostForm("password", "Wa123456")
	passwordAgain := context.DefaultPostForm("password-again", "Wa123456")
	println("email", email, "password", password, "password again", passwordAgain)
}

UserRegisterМетод использует новый способ принятия параметров формы, отправленных запросом Post,PostFormиDefaultPostForm.PostFormпринимает параметры напрямую, аDefaultPostFormМожно установить значение по умолчанию. Если внешний интерфейс не передает значение, мы можем установить значение по умолчанию, например, приведенный выше код.Если внешний интерфейс не передает пароль, мы можем установить пароль по умолчанию.

Когда мы запускаем и печатаем, мы можем ясно видеть наш ввод в форме на консоли.

Когда наш проект полностью функционален, мы можем улучшить наши модульные тесты.

Модульные тесты на этом этапе немного сложнее.

Прежде всего, нам нужно создать структуру, которая поможет нам хранить информацию, которую мы хотим отправить в форму, и в то же время указать информацию заголовка запроса.

func TestUserPostForm(t *testing.T) {
	value := url.Values{}
	value.Add("email", "youngxhui@gmail.com")
	value.Add("password", "1234")
	value.Add("password-again", "1234")
	w := httptest.NewRecorder()
	req, _ := http.NewRequest(http.MethodPost, "/user/register", bytes.NewBufferString(value.Encode()))
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded; param=value")
	router.ServeHTTP(w, req)
	assert.Equal(t, http.StatusOK, w.Code)
}

После того, как модульный тест написан, вы можете запустить модульный тест и обнаружить, что консоль разрешает данные, которые мы написали в тесте.

привязка модели

В примере мы формируем только три параметра передачи, если в последнем проекте было больше дюжины параметров, запись каждого снова занимает очень много времени и очень много опыта. Здесь метод совершенствуется

Gin обеспечивает привязку модели, которая точно так же связывает данные формы с нашей моделью. GIn единообразно инкапсулирует данные в модель, что нам удобно использовать в дальнейшем.

Сначала определите нашу модель, создайте новуюmodelпапка, создатьuserModel.go

package model

type UserModel struct {
	Email         string `form:"email"`
	Password      string `form:"password"`
	PasswordAgain string `form:"password-again"`
}

пройти черезform:"email"соответствоватьemailВведите данные для привязки. Тогда надо модифицироватьHandlerметод.

func UserRegister(context *gin.Context) {
   var user model.UserModel
   if err := context.ShouldBind(&user); err != nil {
   	println("err ->", err.Error())
   	return
   }
   println("email", user.Email, "password", user.Password, "password again", user.PasswordAgain)
}

На данный момент привязка нашей модели написана, запуститеTestUserPostFormТест-кейсы, тест-кейсы можно пройти отлично. Показывает, что наш подход к связыванию модели правильный. При этом привязка модели еще отjson,xml,ymlСвязывание данных в других форматах будет представлено и объяснено в будущем. Конечно, также можно отправить через регистрационную форму в браузере.

Проверка достоверности данных

Любой, кто занимается back-end разработкой, понимает истину: никогда не доверяйте данным, присланным из front-end. Все данные должны быть проверены при входе в бэкэнд.

доступно в моделиbindingдля проверки данных. Джин использует для проверки данныхvalidator.v8Библиотека, предоставляющая различные методы проверки. пройти черезbinding:""способ проверки данных.

мы будемUserModelВнесите изменения, добавьте некоторые правила, проверку электронной почты и проверку пароля и потребуйте, чтобы второй повторяющийся пароль совпадал с первым паролем. Дополнительные правила проверки см.официальная документация

type UserModel struct {
	Email         string `form:"email" binding:"email"`
	Password      string `form:"password"`
	PasswordAgain string `form:"password-again" binding:"eqfield=Password"`
}

Мы переписываем тестовый пример, чтобы проверить правильность проверки почтового ящика и пароля.

func TestUserPostFormEmailErrorAndPasswordError(t *testing.T) {
	value := url.Values{}
	value.Add("email", "youngxhui")
	value.Add("password", "1234")
	value.Add("password-again", "qwer")
	w := httptest.NewRecorder()
	req, _ := http.NewRequest(http.MethodPost, "/user/register", bytes.NewBufferString(value.Encode()))
	req.Header.Add("Content-Type", "application/x-www-form-urlencoded; param=value")
	router.ServeHTTP(w, req)
	assert.Equal(t, http.StatusOK, w.Code)
}

Запустите тест и обнаружите, что хотя тест проходит, будут две строкиerrorИнформация

err ->  Key: 'UserModel.Email' Error:Field validation for 'Email' failed on the 'email' tag
Key: 'UserModel.PasswordAgain' Error:Field validation for 'PasswordAgain' failed on the 'eqfield' tag

Эта информация описывает нашуEmailиPasswordAgainПроверка информации о проверке информации.

Используйте журнал и перенаправление

Тест пройден, потому что код состояния 200 будет возвращен независимо от нашего кода, который не соответствует спецификации кода состояния http, поэтому нам необходимо нормализовать код состояния http. В то же время мы использовали предыдущий кодPrintfРаспечатка информации журнала также не стандартизирована, т.к.PrintfПечатная информация журнала относительно ограничена, поэтому ее следует выбратьLogЗаймитесь печатью журнала.

func UserRegister(context *gin.Context) {
	var user model.UserModel
	if err := context.ShouldBind(&user); err != nil {
		log.Println("err ->", err.Error())
		context.String(http.StatusBadRequest, "输入的数据不合法")
	} else {
		log.Println("email", user.Email, "password", user.Password, "password again", user.PasswordAgain)
		context.Redirect(http.StatusMovedPermanently, "/")
	}
}

Сначала мы будем использовать толькоPrintlnПечатные данные были изменены наlogдля печати данных.

В то же время исходные коды состояния были изменены, и разные коды состояния представляют разные результаты ответа на запрос.

Наконец, когда запрос выполнен успешно, мы перенаправляем маршрут и переходим со страницы на домашнюю страницу.

В то же время нам также необходимо изменить код состояния возврата в тестовом примере.

Суммировать

В этом разделе есть относительно подробное введение в отправку формы, привязку модели и проверку данных, Код также использует различные тестовые примеры для проверки правильности кода.

Код для этой главы

Github

Указатель других глав

Джин (1): Привет
Джин (2): маршрутизатор маршрутизации
Джин (три): шаблон tmpl
Джин (четыре): проверка отправки формы и привязка модели
Джин (5): подключиться к MySQL
Джин (шесть): загрузка файла
Джин (семь): использование и определение промежуточного программного обеспечения Джин (8): использование файлов cookie

Личный публичный аккаунт

Последние статьи будут опубликованы в общедоступном аккаунте, приглашаем всех обратить внимание