[手把手教程][JavaWeb]優(yōu)雅的SSM應用(三)
文章正式改名為:[手把手教程][JavaWeb]優(yōu)雅的SSM應用
這幾天一直在踩坑指郁,為什么這么說呢,主要是一直自己沒找到優(yōu)雅的方式來實現(xiàn)一些東西宏侍。
雖然說前面也做了一些功能模塊,但是總感覺不對勁,畢竟也是剛轉做后端。
為了方便手機端用戶路幸,盡量使用簡單的markdown語法和簡單的頁面結構。
后面朋友給了我一些他們公司同事寫的demo付翁,雖然說不上是牛逼的作品劝赔,但是確實符合我現(xiàn)在的需要。畢竟人家的實現(xiàn)方式也是經過實戰(zhàn)項目演練出來的胆敞。
- 再次安利一波,博客地址:acheng1314.cn
工具
- IDE為idea15
- JDK環(huán)境為1.8
- maven版本為maven3
- Mysql版本為5.5.27
- Tomcat版本為7.0.52
- 流程圖繪制(xmind)
本期目標
- 倉庫管理系統(tǒng)的登錄注冊模塊實現(xiàn)
- 其他一些開發(fā)細節(jié)的體現(xiàn)
- 功能模塊分層設計的具體實現(xiàn)
其他
- 我這姑且算是文章吧,文章都是先用有道云筆記寫的杂伟,然后在簡書上面查看有沒有沖突移层,最后再放到稀土掘金上面
- 但是稀土掘金上面文章出問題了,反饋上去也沒能解決赫粥,本來想抓包看看他們的數(shù)據(jù)的观话,后面還是沒做
- ···其他想說的就太多了,但都是不是今天的主題越平。
注冊
首先频蛔,我們webapp要實現(xiàn)用戶登錄,必須得能新建用戶秦叛。所以晦溪,我們先把注冊用戶放在前面。
- 預期功能:
- 打開注冊頁面
- 填寫注冊信息
- 點擊注冊
- 顯示注冊后的提示信息
有了功能后挣跋,我們就能大概明白我們是想要一個什么樣子的注冊模塊了。
- 一個web注冊頁面
- web頁面能進行基本的數(shù)據(jù)效驗
- 服務器能存儲用戶的注冊信息
- 注冊動作完成后,返回提示頁面歧胁。
一般的包竹,我們在開發(fā)中,有了大概樣子的功能模塊查库,我們需要整理一下業(yè)務流程和程序執(zhí)行流程(在企業(yè)開發(fā)中路媚,有項目經理的話,一般這些都是他們整理出來的樊销,我們只需要開發(fā)實現(xiàn)就行整慎。)經過一番撓頭脏款,大概的流程圖如下所示:
![ssm應用三-注冊流程](http://acheng1314.cn/wp-content/uploads/2016/10/ssm%E5%BA%94%E7%94%A8%E4%B8%89-%E6%B3%A8%E5%86%8C%E6%B5%81%E7%A8%8B.png)
上圖說明:
- 我們在web頁面完成注冊信息的填寫后,我們需要在web頁面做一些基本的數(shù)據(jù)效驗院领。當然后面我們會演示弛矛。
- 注冊信息通過基本的驗證后,我們直接提交到服務器比然,tomact → servelt → spring 丈氓。我們的后端程序,一切都被spring接管了强法,所以万俗,我們需要在spring中完成這些功能。
- spring和外界通信饮怯,我們都是在Controller中完成闰歪。所以我們在Controller中處理數(shù)據(jù)。
- 當數(shù)據(jù)通過了Controller中的校驗后蓖墅,我們需要在Controller中來查找數(shù)據(jù)庫是否存在同樣的用戶名库倘,通用的數(shù)據(jù)操作流程如:Controller → Service → Dao。
- 前面我們提到過论矾,Service是為我們的程序提供服務的教翩,我們盡量每個Service對應一個Dao,這樣我們只需要提供單一的數(shù)據(jù)驅動贪壳,在外層進行業(yè)務組裝饱亿,這樣就能達到我們的目的,同樣的闰靴,我們這樣也能將程序解耦彪笼,以后的維護也就相對簡單了。
好的蚂且,我們上面已經把思路想明白了∨涿ǎ現(xiàn)在我們接著就開始實戰(zhàn)。
- 生成注冊頁面的連接杏死。
我們要生成一個連接章姓,經過查找資料,我們知道我們需要創(chuàng)建一個Controller的類识埋。代碼如下:
@Controller
@RequestMapping("/mvc")
public class MainController {
/**
* 登陸頁面
* @return
*/
@RequestMapping(value = "/login",method = RequestMethod.GET)
public String login(){
return "login";
}
}
在上面我們使用了@Controller和@RequestMapping("/mvc")注解凡伊。詳細資料點這里。
通俗的來說窒舟,我們需要在我們前面配置的Controller路徑中系忙,建立使用@Controller的注解的類告訴Spring這是一個控制器。
在類上面的 @RequestMapping("/mvc") 惠豺,是說明這個類的訪問地址是 /mvc 银还。
在方法上面的 @RequestMapping(value = "/login",method = RequestMethod.GET) 风宁,是說明我這個方法的訪問地址是 /mvc/login ,請求方式是http請求的get方式蛹疯。
這里我的方法是String方法戒财,則是直接返回一個web頁面的名字。
當然捺弦,我們并不需要說直接去設定某個jsp文件饮寞。我們需要的是在這里指定好名稱,然后使用對應的自動完成就能創(chuàng)建出那個jsp文件列吼。
然后我們直接在jsp文件中填寫對應的代碼就行了幽崩。
好的,基本的東西我們都說了寞钥,那么我們先去百度找一個登錄界面(一定要能看慌申,不能那啥太直接的粗糙的東西,畢竟我們都是有品位的人)理郑。如下圖:
![ssm應用三-登錄注冊頁面](http://acheng1314.cn/wp-content/uploads/2016/10/ssm%E5%BA%94%E7%94%A8%E4%B8%89-%E7%99%BB%E5%BD%95%E6%B3%A8%E5%86%8C.png)
上面的圖中樣子還不錯的樣子蹄溉,同時他們還是同一個頁面,這下就很nice了您炉,又可以少寫一個界面了类缤。
按照前面兩期我們的東西綜合起來,我們需要先把CSS邻吭、JS、圖片等東西宴霸,扔到我們的靜態(tài)目錄中囱晴。如下圖所示:
![ssm應用三-登錄注冊靜態(tài)資源](http://acheng1314.cn/wp-content/uploads/2016/10/ssm%E5%BA%94%E7%94%A8%E4%B8%89-%E7%99%BB%E5%BD%95%E6%B3%A8%E5%86%8C%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90.png)
接著我們把登錄的html的頁面的東西,全部放到login.jsp中瓢谢。如下:
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%-- 上面這兩行是java代碼的引用 --%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<script type="text/javascript" src="/static/js/jquery-3.1.1.min.js"></script>
<head>
<title>倉庫管理系統(tǒng)→登錄</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<script type="text/javascript" src="/static/js/login.js"></script>
<link href="/static/css/login2.css" rel="stylesheet" type="text/css"/>
</head>
<html>
<body>
<h1>倉庫管理系統(tǒng)登陸注冊<sup>2016</sup></h1>
<div class="login" style="margin-top:50px;">
<div class="header">
<div class="switch" id="switch"><a class="switch_btn_focus" id="switch_qlogin" href="javascript:void(0);"
tabindex="7">快速登錄</a>
<a class="switch_btn" id="switch_login" href="javascript:void(0);" tabindex="8">快速注冊</a>
<div class="switch_bottom" id="switch_bottom" style="position: absolute; width: 64px; left: 0px;"></div>
</div>
</div>
<div class="web_qr_login" id="web_qr_login" style="display: block; height: 235px;">
<!--登錄-->
<div class="web_login" id="web_login">
<div class="login-box">
<div class="login_form">
<form action="<%=request.getContextPath()%>/userAction/login" name="loginform"
accept-charset="utf-8" id="login_form" class="loginForm"
method="post"><input type="hidden" name="did" value="0"/>
<input type="hidden" name="to" value="log"/>
<div class="uinArea" id="uinArea">
<label class="input-tips" for="u">帳號:</label>
<div class="inputOuter" id="uArea">
<input type="text" id="u" name="loginId" class="inputstyle"/>
</div>
</div>
<div class="pwdArea" id="pwdArea">
<label class="input-tips" for="p">密碼:</label>
<div class="inputOuter" id="pArea">
<input type="password" id="p" name="pwd" class="inputstyle"/>
</div>
</div>
<div style="padding-left:50px;margin-top:20px;">
<input type="submit" value="登 錄"
style="width:150px;"
class="button_blue"/></div>
</form>
</div>
</div>
</div>
<!--登錄end-->
</div>
<!--注冊-->
<div class="qlogin" id="qlogin" style="display: none; ">
<div class="web_login">
<form name="form2" id="regUser" accept-charset="utf-8" action="<%=request.getContextPath()%>/userAction/reg"
method="post">
<input type="hidden" name="to" value="reg"/>
<input type="hidden" name="did" value="0"/>
<ul class="reg_form" id="reg-ul">
<div id="userCue" class="cue">快速注冊請注意格式</div>
<li>
<label for="user" class="input-tips2">用戶名:</label>
<div class="inputOuter2">
<input type="text" id="user" name="loginId" maxlength="16" class="inputstyle2"/>
</div>
</li>
<li>
<label for="user" class="input-tips2">姓名:</label>
<div class="inputOuter2">
<input type="text" id="name" name="name" maxlength="16" class="inputstyle2"/>
</div>
</li>
<li>
<label for="passwd" class="input-tips2">密碼:</label>
<div class="inputOuter2">
<input type="password" id="passwd" name="pwd" maxlength="16" class="inputstyle2"/>
</div>
</li>
<li>
<label for="passwd2" class="input-tips2">確認密碼:</label>
<div class="inputOuter2">
<input type="password" id="passwd2" name="" maxlength="16" class="inputstyle2"/>
</div>
</li>
<li>
<label for="cellNumber" class="input-tips2">手機號:</label>
<div class="inputOuter2">
<input type="text" id="cellNumber" name="cellNumber" maxlength="18" class="inputstyle2"/>
</div>
</li>
<li>
<label for="sex" class="input-tips2">性別:</label>
<div class="inputOuter2">
<input type="text" id="sex" name="sex" maxlength="18" class="inputstyle2"/>
</div>
</li>
<li>
<label for="age" class="input-tips2">年齡:</label>
<div class="inputOuter2">
<input type="age" id="age" name="age" maxlength="18" class="inputstyle2"/>
</div>
</li>
<li>
<div class="inputArea">
<input type="button" id="reg" style="margin-top:10px;margin-left:85px;" class="button_blue"
value="同意協(xié)議并注冊"/> <a href="#" class="zcxy" target="_blank">注冊協(xié)議</a>
</div>
</li>
<div class="cl"></div>
</ul>
</form>
</div>
</div>
<!--注冊end-->
</div>
<div class="jianyi">*推薦使用ie8或以上版本ie瀏覽器或Chrome內核瀏覽器訪問本站</div>
</body>
</html>
上面的網(wǎng)頁代碼中的東西畸写,我們也可以不求甚解,只要會調用就行氓扛。調用地址是在我們的form表單的action那里填寫我們的服務器地址枯芬。這里我們甚至可以做前后端分離,用純粹的html+js來調用Api接口實現(xiàn)前后端分離采郎。
action="<%=request.getContextPath()%>/userAction/reg" method="post"
<%=request.getContextPath()%> 這是指向我們應用的根路徑
mothod是說明我們請求的方式千所,我們這里才用了post,至于其他的方法就不一一介紹了蒜埋,詳細信息請百度查找“ http請求 ”
form表單中淫痰,每個input的name我們需要和后端的接口那邊的字段對應。
當我們的字段對應后整份,spring可以自動把請求的內容轉換為適應的對象待错。
小提示:我們可以直接debug我們的程序籽孙,只要取消斷點程序就可以順序執(zhí)行,加入斷點只要程序流轉到那里火俄,他就會自動調試犯建。
當然,我們的jsp寫完后瓜客,我們需要給我們的表單請求那里指定請求路徑适瓦。由于上面我已經指定了路徑,所以我們需要在對應的路徑創(chuàng)建請求的接口(實際開發(fā)中都是先寫好請求接口忆家,再讓程序調用犹菇。由于我這里是提前寫好的,所以這里我們得照著路徑寫代碼)芽卿。
我們在Controller目錄下創(chuàng)建一個UserController類揭芍,代碼內容如下:
package cn.acheng1314.mvc.controller;
import cn.acheng1314.domain.ResponseObj;
import cn.acheng1314.domain.User;
import cn.acheng1314.exception.*;
import cn.acheng1314.service.serviceImpl.UserServiceImpl;
import cn.acheng1314.utils.GsonUtils;
import cn.acheng1314.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
/**
* 用戶請求相關控制器
* <br/>Created by acheng on 2016/9/26.
*/
@Controller
@RequestMapping("/userAction")
public class UserController {
@Autowired
private UserServiceImpl userService; //自動載入Service對象
private ResponseObj responseObj; //bean對象
/**
* 為什么返回值是一個ModelAndView,ModelAndView代表一個web頁面<br/>
* setViewName是設置一個jsp頁面的名稱
* @param req http請求
* @param user 發(fā)起請求后卸例,spring接收到請求称杨,然后封裝的bean數(shù)據(jù)
* @return 返回一個web頁面
* @throws Exception
*/
@RequestMapping(value = "/reg", method = RequestMethod.POST)
public ModelAndView reg(HttpServletRequest req, User user) throws Exception {
ModelAndView mav = new ModelAndView(); //創(chuàng)建一個jsp頁面對象
mav.setViewName("home"); //設置JSP文件名
if (null == user) {
mav.addObject("message", "用戶信息不能為空!"); //加入提示信息筷转,在jsp中我們直接使用${對象名稱}就能獲取對應的內容
return mav; //返回頁面
}
if (StringUtils.isEmpty(user.getName()) || StringUtils.isEmpty(user.getPwd())) {
mav.addObject("message", "用戶名或密碼不能為空姑原!");
return mav;
}
if (null != userService.findUser(user)) {
mav.addObject("message", "用戶已經存在!");
return mav;
}
try {
userService.add(user);
} catch (Exception e) {
e.printStackTrace();
mav.addObject("message", "錯誤:用戶其他信息錯誤");
return mav;
}
mav.addObject("code", 110);
mav.addObject("message", "恭喜呜舒。注冊成功");
req.getSession().setAttribute("user", user);
return mav;
}
/**
* 登錄接口
* @param req
* @param user
* @return
*/
@RequestMapping(value = "/login", method = RequestMethod.POST, produces = {
"application/json; charset=utf-8"})
@ResponseBody
public ModelAndView login(HttpServletRequest req, User user) {
ModelAndView mav = new ModelAndView("home");
String result;
if (null == user) {
responseObj = new ResponseObj<User>();
responseObj.setCode(ResponseObj.EMPUTY);
responseObj.setMsg("登錄信息不能為空");
result = GsonUtils.gson.toJson(responseObj); //轉換的json數(shù)據(jù)
mav.addObject("result", result);
return mav; //返回頁面
}
if (StringUtils.isEmpty(user.getLoginId()) || StringUtils.isEmpty(user.getPwd())) {
responseObj = new ResponseObj<User>();
responseObj.setCode(ResponseObj.FAILED);
responseObj.setMsg("用戶名或密碼不能為空");
result = GsonUtils.gson.toJson(responseObj);
mav.addObject("result", result);
return mav;
}
//查找用戶
User user1 = userService.findUser(user);
if (null == user1) {
responseObj = new ResponseObj<User>();
responseObj.setCode(ResponseObj.EMPUTY);
responseObj.setMsg("未找到該用戶");
result = GsonUtils.gson.toJson(responseObj);
} else {
if (user.getPwd().equals(user1.getPwd())) {
responseObj = new ResponseObj<User>();
responseObj.setCode(ResponseObj.OK);
responseObj.setMsg(ResponseObj.OK_STR);
result = GsonUtils.gson.toJson(responseObj);
} else {
responseObj = new ResponseObj<User>();
responseObj.setCode(ResponseObj.FAILED);
responseObj.setMsg("用戶密碼錯誤");
result = GsonUtils.gson.toJson(responseObj);
}
}
mav.addObject("result", result);
return mav;
}
}
當然很多數(shù)據(jù)效驗我們不能只在后端做锭汛,我們需要將數(shù)據(jù)檢查的粒度細化。
不但要在后端做袭蝗,而且我們的前端頁面也要做的唤殴,比如說手機號、郵箱帳號到腥、用戶名規(guī)則等等朵逝,用的最多的也就是web頁面上面拿到數(shù)據(jù)用js來判斷,使用正則表達式來判斷是否符合標準乡范。
具體的js我也就不寫了配名,因為我也不是很了解JS,只能對著別人寫的自己來做修改==
好的晋辆,我們現(xiàn)在已經把東西都弄完了渠脉,debug開啟程序,然后加入斷點調試瓶佳。運行結果如下:
![ssm應用三-注冊頁面和調試](http://acheng1314.cn/wp-content/uploads/2016/10/ssm%E5%BA%94%E7%94%A8%E4%B8%89-%E6%B3%A8%E5%86%8C%E9%A1%B5%E9%9D%A2%E5%92%8C%E8%B0%83%E8%AF%95.png)
這樣我們現(xiàn)在能拿到對應的數(shù)據(jù)连舍,并且在Controller中加入了數(shù)據(jù)校驗。同時,我們的web頁面中也加入了js驗證索赏。
現(xiàn)在我們的注冊頁面也可以了盼玄,功能也有了。既然如此潜腻,我們應該接著把登錄頁面做成功埃儿,但是我們已經有了這個的思路,那么剩下的只需要依樣畫瓢就能完成融涣。
具體的東西童番,都已經在后面的代碼中貼出來了。詳情請看github:
項目地址:點擊訪問github
總結:
- URL生成
- 注冊登錄完成
- 簡單的前端驗證(在代碼包中可以看到)
- form表單提交
- http請求
- 功能模塊分析
- 流程圖(使用xmind制作)
下期預告:完整的后臺主頁威鹿,前端使用json數(shù)據(jù)剃斧,列表數(shù)據(jù)分頁。