为了程序执行效率、数据完整性和程序健壮性,我们的前端必须做对应的基础数据效验,后端的控制器必须做所有需要的数据的效验。
前端数据效验我们使用js完成,界面样式是由CSS完成,网络请求采用异步请求,具体的实现是使用的ajax完成。
js获取web页面数据统一使用标签的ID,格式为:$("#标签ID")
web页面标签最好一个标签一行,这样代码看起来更加舒服
后端接口返回数据为json,前端页面解析json控制程序流转
很多时候我们要先引入相关的辅助JS
数据检验JS代码
function checkLoginInfo() {
if ("" == $("#u").val()) {
$("#u").tips({
side: 2,
msg: '用户名不得为空',
bg: '#AE81FF',
time: 3
});
$("#u").focus();
return false;
}
if ($("#p").val() == "") {
$("#p").tips({
side: 2,
msg: '密码不得为空',
bg: '#AE81FF',
time: 3
});
$("#p").focus();
return false;
}
return true;
}
登录的js代码
function webLogin() {
if (checkLoginInfo()) {
var loginname = $("#u").val();
var password = $("#p").val();
$.ajax({
type: "POST",
url: '<%=request.getContextPath()%>/userAction/login',
data: {loginId: loginname, pwd: password},
dataType: 'json', //当这里指定为json的时候,获取到了数据后会自动解析的,只需要返回值.字段名称 就可以了
cache: false,
success: function (data) {
if (data.code == 1) {
window.location.href = data.data.nextUrl; //拿到服务器返回的地址,然后进行跳转操作
//window.location.href = '<%=request.getContextPath()%>/mvc/home'; //跳转到主页*/
} else {
alert(data.msg);
$("#u").focus();
}
}
});
}
}
注册的JS代码
function webReg() {
if ($('#user').val() == "") {
$('#user').focus();
$("#user").tips({
side: 2,
msg: '用户名不能为空',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#user').val().length < 4 || $('#user').val().length > 16) {
$('#user').focus();
$("#user").tips({
side: 2,
msg: '用户名位6-16字符',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#name').val().length < 2
|| $('#name').val().length > 16
|| $('#name').val() == "") {
$('#name').focus();
$("#name").tips({
side: 2,
msg: '用户姓名必须为4-16位字符',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#passwd').val().length < 6) {
$('#passwd').focus();
$("#passwd").tips({
side: 2,
msg: '密码不能小于6位',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#passwd2').val() != $('#passwd').val()) {
$('#passwd2').focus();
$("#passwd2").tips({
side: 2,
msg: '两次密码不一致',
bg: '#AE81FF',
time: 3
});
return false;
}
var sqq = /^1[34578]\d{9}$/;
if (!sqq.test($('#phoneNumber').val())
|| $('#phoneNumber').val().length < 11
|| $('#phoneNumber').val().length > 14
|| $('#phoneNumber').val() == "") {
$('#phoneNumber').focus();
$("#phoneNumber").tips({
side: 2,
msg: '手机号不正确',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#sex').val() == "") {
$('#sex').focus();
$("#sex").tips({
side: 2,
msg: '性别不能为空',
bg: '#AE81FF',
time: 3
});
return false;
}
if ($('#age').val() == "") {
$('#age').focus();
$("#age").tips({
side: 2,
msg: '年龄不能为空',
bg: '#AE81FF',
time: 3
});
return false;
}
var loginname = $("#user").val();
var password = $("#passwd").val();
var username = $("#name").val();
var cellNumber = $("#phoneNumber").val();
var sex = $("#sex").val();
var age = $("#age").val();
$.ajax({
type: "POST",
url: '<%=request.getContextPath()%>/userAction/reg',
data: {loginId: loginname, pwd: password, name: username, sex: sex, age: age, cellNumber: cellNumber},
dataType: 'json',
cache: false,
success: function (data) {
if (data.code == 1) {
window.location.href = data.data.nextUrl;
} else {
alert(data.msg);
$("#user").focus();
}
}
});
}
上面的注释已经能很明显的看出我们的 前端效验、网络请求和js解析json,下面我们在前端页面中调用这个js,如下:
<form action="" //此处必须删掉form表单的地址
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="button"
id="btn_login"
value="登 录"
onclick="webLogin();" //此处调用我们上面写的js的登录方法
style="width:150px;"
class="button_blue"/>
</div>
</form>
主要就是在onclick
中添加js函数
前端页面:
FORM表单必须删除action的值
input type="submit"
要改为input type="button"
前端页面完成后,我们必须在后端接口处,做出对应的修改,让他符合我们前端的调用规则。
后端修改如下:
登录接口,因为json数据外层一般都是Object类型,所以返回值必须是Object
如果之前返回的是ModelAndView
,现在要改为Object
错误405
也许有人问,如果我不改会怎样
这个错误的意思是
Request method 'POST' not supported
POST方法不被允许The method received in the request-line is known by the origin server but not supported by the target resource.
不支持接收这种类型的数据对于请求所标识的资源,不允许使用请求行中所指定的方法
如果把POST
请求换成GET
请求可以吗
答案是不可以的,因为登录你需要传数据到后台,所以你要用POST
把数据传给后台
在网上还有人说是路径问题
不过使用绝对路径是没错的
<%=request.getContextPath()%>
是为了解决相对路径的问题,可返回站点的根路径。
<%=request.getContextPath()%>/userAction/login
解决方法:
把返回的数据ModelAndView
,现在要改为Object
ModelAndView
就是一个map
集合
一旦Controller
处理完客户请求,则返回ModelAndView
对象给DispatcherServlet
前端控制器。ModelAndView
中包含了模型(Model)
和视图(View)
从宏观角度考虑,DispatcherServlet
是整个Web
应用的控制器;
从微观角度考虑,Controller
是单个Http
请求处理过程中的控制器,
ModelAndView
是Http
请求过程中返回的模型和视图。前端控制器返回的视图可以是视图的逻辑名,或者实现了View
接口的对象。View
对象能够渲染客户响应结果。其中,ModelAndView
中的模型能够供渲染View
时使用。借助于Map
对象能够存储模型。
通过上面的重构可以明白以下几点:
前端
js实现基本的数据效验,发起网络请求(具体实现用ajax),返回类型设置json能自动解析,获取页面控件,页面控件调用js
js获取解析后的json数据的值,进行程序流转控制
后端:
后端控制器必须申明,后端的地址必须配置,每个地址返回的数据类型要匹配,返回json数据,方法上面必须配置:@ResponseBody
可以使用工具类来方便开发
关于在HTML里引入图片,css等资源
一般采用相对路径
获取某个资源的相对路径可以这么做
对资源点击右键→
Copy Relative Path
获取相对路径
选取一个比较喜欢的后端主页,然后把对应的资源放入到对应的文件目录(js、css、images等),需要新加入的资源如果在以前的目录中没有的话,那么需要在里面进行配置。比如说这里加入了字体文件,那么现在需要先把字体文件指定目录为:
static/font/
目录指定后需要在Spring
的配置文件,spring-web.xml
中配置静态资源的目录如下:
<mvc:resources mapping="/fonts/**" location="/static/fonts/"/>
有文件的信息上传
关于文件上传
前端写完数据发送,后端写完controller后
还要在Spring的配置文件中添加文件的支持设置,不然无论如何都收不到文件(文件一直为null)
补充配置文件,spring-web.xml
新增配置如下:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--下面设置的是上传文件的最大大小-->
<property name="maxUploadSize" value="10000000"/>
</bean>
Spring
接收文件上传时,Controller
的具体方法的参数前面插入注解,同时数据类型是MultipartFile
。
js进行前端流程控制,后端接口隔离,前后端解耦。
主要参考于大牛Clone丶记忆的SSM集成之路
网友评论