文章目录
- Ajax
- 1. 同步请求异步请求
- 2. Ajax实现方式
- 3. 日程管理第四期
- 4. 响应JSON串
- 4.1 响应JSON串格式的一般格式
- Appendix
Ajax
发送请求的一些方式
1.输入浏览器回车
2.html>head>script/link
img标签
3.a标签form表单标签等
用户手动控制提交产生;
4.通过js代码产生请求;
Ajax的原理,通过js技术向后端发送请求,通过响应来进行判断是否 进行页面跳转,是否生成数据展示到dom树中
AJAX 最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容。
1. 同步请求异步请求
2. Ajax实现方式
-
假如按钮触发了一个名为getmesssgae的js函数
-
script部分
<script>
function getmessage(){
// 1.实例化一个xmlHttpRequest对象
var req = new XMLHttpRequest;
// 2.设置xmlHttpRequest回调函数
// 3.设置发送请求的方式和请求资源路径
req.open("GET","/hello?username=zhangsan");
// 4.发送请求
req.send();
}
</script>
第二部分的代码有点多,很难写
- 往页面上做出响应的代码*
req.onreadystatechange = function(){
if(req.readyState==4&&req.status==200);
// alert("后端响应了")
console.log(req.responseText)
//将信息放到指定的位置
var inputEle = document.getElementById("message")
inputEle.value = req.responseText
}
- 进行页面跳转*
window.location.href="http://www.atguigu.com"
3. 日程管理第四期
注册提交前进行校验用户名是否占用功能;
也就是前端checkUsername函数 校验完格式后,继续进行是否占用校验 并修改 usernameMsg信息
- 创建XMLHTTPRequest对象
var req = new XMLHTTPRequest()
- 设置回调函数
req.openstatechange = function(){
if(req.status ==200 && req.readyState = 4){
usernameMsg.innerText = req.responseText;
}
}
- 设置请求方式和 资源路径映射
req.open(“GET”,”user/checkUserUsed?username=”+username)
- 发送请求
req.send()
使用Ajax技术在不跳转的情况下响应到前端页面
//控制层新增函数checkUsernameUsed
/**
* 注册时接收要注册的username,目的是检测其是否 合法是否被占用
* @param req
* @param resp
*/
protected void checkUsernameUsed(HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 接收用户名
String username = req.getParameter("username");
// 服务层进行查询该用户名是否存在用户
int username1 = userService.findUsername(new SysUser(null, username, "******"));
// 如果有响应已占有
// 如果没有响应可用
/**
* 0表示没查出来 username
* 1表示 占用
*/
String info = null;
if (username1==0){
info="可用";
}else if (username1==1){
info="不可用";
}
resp.getWriter().write(info);
}
注意:本次开发传参仅传入username,但是会设置一个密码,这个密码必须不为空,因为后续代码逻辑会送入MD5校验,为空报错;
密码直接设置为
******
前端代码 会进行校验格式;用户无法起此代码
4. 响应JSON串
JSON串解决问题如下
-
响应乱码问题
-
响应信息格式问题
后端响应的信息应该是JSON格式,前后端共同尊守;
如果响应可用不可用;前后端需要保持一致,就很麻烦,后端代码进行修改了,那么前端也需要跟着改;
统一的格式是前后端商量好的
- 校验不通过无法阻止表单提交
4.1 响应JSON串格式的一般格式
{
响应行 状态码200,404…
响应头
响应体 { code:”1成功/0失败”, message:业务状态码,“data”:{} }
}
响应报文如上图所示;
所谓的JSON串格式写的是 响应体中的东西
响应行必须触发,把东西响应回来,因此响应行状态码必须是200
响应体中的码是前后端提前商量好的;
code 业务状态码
message 业务状态码的补充说明
data 本次响应数据 具体内容根据业务相关
- 具体流程
我们使用jacksonlib包 转化json格式,减少后端程序员拼写字符串的难度
后端程序员撰写响应体的 class ,后续使用,直接new对象,将我们业务数据封装进去即可
public class Result<T> {
private Integer code;
private String message;
private T data;
}
-
后续会将Result对象使用jackon转化为json串
-
关于业务码code使用枚举形式进行定义,用的时候直接拿来用即可
public enum ResultCodeEnum {
/**
* 此处创建枚举对象,自动的调用下面的构造器;
*/
SUCCESS(200,"success"),
USER_ERROR(501,"usernameError"),
PASSWORD_ERROR(503,"passwordError"),
NOT_LOGIN(504,"notLogin"),
USER_USED(505,"usernameUsed");
private Integer code;
private String message;
ResultCodeEnum(Integer code, String message) {
this.code = code;
this.message = message;
}
}
- 此处创建枚举对象,自动的调用下面的构造器;
- 枚举常量通常使用大写字母表示,默认常量 不可修改;
- 枚举本身是一个类,具有类的所有成分,每一个枚举常量都是枚举类的实例,因此可以看出上面写法;
- 创建Result类 未来后端传递数据使用Result对象即可;
package schedule.common;
/**
* 全局统一响应的JSON格式处理类
*
*/
public class Result<T> {
// 返回码
private Integer code;
// 返回消息
private String message;
// 返回数据
private T data;
public Result(){}
// 返回数据
protected static <T> Result<T> build(T data) {
Result<T> result = new Result<T>();
if (data != null)
result.setData(data);
return result;
}
/**
* 对上一个build的重载,除了设置data以外,还要进行code,message的设置;
* @param body
* @param code
* @param message
* @return
* @param <T>
*/
public static <T> Result<T> build(T body, Integer code, String message) {
Result<T> result = build(body);
result.setCode(code);
result.setMessage(message);
return result;
}
public static <T> Result<T> build(T body, ResultCodeEnum resultCodeEnum) {
Result<T> result = build(body);
result.setCode(resultCodeEnum.getCode());
result.setMessage(resultCodeEnum.getMessage());
return result;
}
/**
* 操作成功,默认是将数据传进去,设置成功的状态码;
* @param data baseCategory1List
* @param <T>
* @return
*/
public static<T> Result<T> ok(T data){
Result<T> result = build(data);
return build(data, ResultCodeEnum.SUCCESS);
}
public Result<T> message(String msg){
this.setMessage(msg);
return this;
}
public Result<T> code(Integer code){
this.setCode(code);
return this;
}
// ------------------------------下面是常规的GetSet方法------------------------------
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
- 因此在后端传递的时候,传递码可以如下表示
Result result = Result.ok();
String info = null;
if (username1==0){
result = result.ok(null);
}else if (username1==1){
result = result.build(null, ResultCodeEnum.USER_USED);
}
- 接下来将result转化为JSON串
- 导入jar包
- 导入jar包后使用ObjectMapper进行 对象–>JSON串转化
// 接下来将result转化为json串响应给客户端
ObjectMapper objectMapper = new ObjectMapper();
String info = objectMapper.writeValueAsString(result);
resp.getWriter().write(info);
对象转JSON串步骤
--导jackson包;
--实例化ObjectMapper对象
--直接使用writeValueAsString即可
- 最终还需要告诉客户端响应json串格式
resp.setContentType("application/json;charset=UTF-8");
- 响应结果如下所示
- 创建WebJson工具类
public class WebJson {
private static ObjectMapper objectMapper;
static {
objectMapper = new ObjectMapper();
}
public static void writeJson(HttpServletResponse resp, Result result){
resp.setContentType("application/json;charset=UTF-8");
try {
String s = objectMapper.writeValueAsString(result);
resp.getWriter().write(s);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
因此所有代码一句话即可
writeJson是一个静态方法,因此这个工具包,调的不是类,是静态方法;可以直接类名.方法进行调用
Appendix
//回调函数不会阻止表单提交;未来使用vue axios 结合promise处理;