1 axios.post 用法
HTTP请求提交方式:GET 和 POST
POST:
axios.post语法
==========================GET=============================
axios.get("servlet地址",{params:{name:'tom',age:12}})
.then(resp=>{})
.catch(exception=>{处理异步交互的异常})
==========================POST=============================
axios.post('servlet地址', {name:'tom',age:20})
.then(response => {
console.info(response)
})
.catch(e => { //捕获异步请求失败情况,服务器500的情况下
console.info(e)
});
axios.get和axios.post发送参数区别
axios.get(url,{params:{}}),这种参数传递时,按照querystring【格式:?key=value&key=value】向控制器发送的,所以controller里面就可以利用request.getParameter();
axios.post(url,对象)这种情况传递参数是,按照jsonstring【格式:{“key”:value,“key”:value}】,控制器 里面对于jsonstring格式无法利用传统request.getParameter()获取中。控制器只能利用jackson的反序列方案解析请求参数。
//1-1 获取请求体
BufferedReader reader = request.getReader();//读取请求体
//1-2 从reader读取字符串
StringBuilder requestBody=new StringBuilder();
String temp;
while((temp=reader.readLine())!=null){
requestBody.append(temp);
}
System.out.println("请求协议发送来的数据有:"+requestBody);
//1-3 依靠ObjectMapper将请求体传递来的jsonstring反序列化成java对象User
ObjectMapper mapper=new ObjectMapper();
Users users = mapper.readValue(requestBody.toString(), Users.class);
细节:axios.post发送参数的方式是:jsonstring,所以控制器处理jsonstring的方式是json字符串的反序列化
在java程序中,将java对象转换为json格式字符串的过程称为JSON序列化;
反之,
在java程序中,将json格式的字符串转换为java对象的过程称为JSON反序列化。
2 物业系统贯穿案例の楼栋管理
添加楼栋
BuildingDao.java和BuildingService.java代码略
building/add.html发送新增请求请求
AddBuildingServlet处理新增楼栋的请求
@WebServlet(name = "AddBuildingServlet", value = "/AddBuildingServlet")
public class AddBuildingServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("新增楼栋的请求以接收到");
//1. axios.post提交的json string数据获取:
// 获取请求协议提交的json String
BufferedReader reader = request.getReader();//读请求体
String temp;
StringBuilder jsonString=new StringBuilder();
while( (temp=reader.readLine())!=null) {
jsonString.append(temp);
}
reader.close();
System.out.println("jsonString的内容是:"+jsonString);
//1-1 json String ----> java对象 json反序列化
ObjectMapper mapper=new ObjectMapper();
WyBuilding building = mapper.readValue(jsonString.toString(), WyBuilding.class);
System.out.println("提交楼栋信息时:"+building);
//保存
//设置浏览器解析响应体格式:json
response.setContentType("application/json;charset=utf-8");
try {
TransactionManagement.getProxyInstance(new WyBuildingServiceImpl()).save(building);
//响应
response.getWriter().write(
mapper.writeValueAsString(
new ResponseResult<>(20000,"新增成功")
)
);
} catch (Exception e) {
e.printStackTrace();//程序员跟踪异常关键节点
//响应
response.getWriter().write(
mapper.writeValueAsString(
new ResponseResult<>(50000,"新增失败,失败原因:"+e.getMessage())
)
);
}
}
}
细节
添加楼栋时,楼栋的建成时间在Servlet中处理时会抛出异常:
这个异常发生的根本原因是:jackson在处理JSON反序列化时,因为请求提交的日期格式和jackson用来转换的格式不一致造成的,怎么解决呢?我们通过分析可以发现:Jackson处理日期时,是根据我们在Building实体类的completed属性的@JsonFormat指定的日期格式进行转换的,
修改楼栋
弹窗式修改楼栋,跟新增楼栋处理就比较相似了。我们跟着以下步骤操作:
批量删除楼栋
需求分析:
批量删除楼栋信息时,我们先要判断用户是否勾选“删除楼栋”,如果没有勾选给出提示消息,勾选了楼栋信息就给控制器发送请求完成删除。
代码实现
BuildingDao.java
@Override
public int batchDelete(Connection conn,Integer… ids) {
StringBuilder sql=new StringBuilder();
sql.append(“delete from wy_building where id in “);
sql.append(”(”);
for(int i=0;i<ids.length;i++){
if(i==ids.length-1){
sql.append(“?”);
continue;
}
sql.append(“?,”);
}
sql.append(“)”);
return Dbutils.noQuary(
conn,
sql.toString(),
ids);
}
BuildingService.java代码略
list.html发送批量删除的请求axios.get发送,servlet处理批量删除请求的querystring参数
axios.get发送批量删除请求,控制器接收数据后的处理思路,参考代码如下:
通过axios.post和axios.get分别处理批量删除案例得出心得:queryString格式和jsonString格式在控制器中处理方式是不一样的
QueryString的请求参数,控制器接收:
String value=request.getParameter(“name”);
根据参数传递时的name接收对应的value,且value一定是String类型
QueryString的请求参数,控制器接收:
request.getReader()读取请求体,再通过ObjectMapper的readValue将读取的请求体(其实就是json字符串)转换为java程序需要的java对象,完成后续的数据处理
登录
UserDao.java和UserService.java代码略
login.html发送异步请求
<el-form :model="user" :rules="rules" ref="loginForm" label-width="100px" class="demo-ruleForm">
<el-form-item label="账号" prop="phone">
<el-input v-model="user.phone" clearable prefix-icon="el-icon-s-custom"></el-input>
</el-form-item>
<el-form-item label="密码" prop="password">
<el-input type="password" v-model="user.password" clearable show-password prefix-icon="el-icon-search"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="submitForm('loginForm')">登录</el-button>
<el-button type="danger" @click="resetForm('loginForm')">重置</el-button>
</el-form-item>
</el-form>
<script>
new Vue({
el: "#app",
data() {
return {
user:{
phone:'13388775566',
password:'123'
}
}
},
methods: {
submitForm(formName) {
this.$refs[formName].validate((valid) => {
if (valid) {//表单验证通过
axios.post("/web/DoLoginServlet",this.user)
.then(resp=>{ })
} else {//表单验证不过
console.log('error submit!!');
return false;
}
});
},
resetForm(formName) {
this.$refs[formName].resetFields();
}
}
})
</script>
DoLoginServlet处理登录请求
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("application/json;charset=utf-8");
try {
BufferedReader reader = request.getReader();
StringBuilder requestBody=new StringBuilder();
String content;//用来保存每次读取到的一行数据
while( (content=reader.readLine())!=null){
requestBody.append(content);
}
reader.close();
System.out.println("requestBody:"+requestBody);
//1-2 json反序列化技术将json字符串转回java对象
WyUser user = new ObjectMapper().readValue(requestBody.toString(), WyUser.class);
//2.调
WyUserServiceImpl proxyInstance = new TransactionalProxyFactory<WyUserServiceImpl>(
new WyUserServiceImpl()
).getTxProxyInstance();
WyUser loginUser = proxyInstance.findByAccount(user.getPhone(), user.getPassword());
response.getWriter().write(
new ObjectMapper().writeValueAsString(
new ResponseResult<>(20000,"登录成功",loginUser)
)
);
} catch (Exception e) {
e.printStackTrace();
String msg=e.getMessage();
if(e instanceof InvocationTargetException){
InvocationTargetException t=(InvocationTargetException)e;
msg=t.getTargetException().getMessage();
}
response.getWriter().write(
new ObjectMapper().writeValueAsString(
new ResponseResult<>(50001,"登录失败,原因:"+msg)
)
);
}
}
细节:
用户登录成功后,需要将登录用户的真实姓名和头像存入浏览器缓存,页面跳转到home.html后,在home页面显示欢迎消息
验证用户登录过滤器
本次过滤器的使用与第二周贯穿案例的过滤器基本一样。登录成功后将用户登录信息保存到session中。需要注意的是在过滤器中需要放行vue和ElementUI的资源访问权限。具体代码如下所示:
@WebFilter("/*")
public class AuthorizeFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
System.out.println("AuthorizeFilter doFilter");
HttpServletRequest req=(HttpServletRequest)request;
HttpServletResponse resp=(HttpServletResponse)response;
HttpSession session = req.getSession();
Object user = session.getAttribute("user");
//2 获取当前用户要进入的是否是登录页面
StringBuffer requestURL = req.getRequestURL();
String requestURI = req.getRequestURI();
System.out.println("requestURL:"+requestURL);
System.out.println("requestURI:"+requestURI);
String url = requestURI.toLowerCase();
if(user!=null
||url.contains("login")
||url.contains("css")
||url.contains("images")
||url.contains("/js/")
||url.contains("/vue/")
||url.contains("/element-ui/")
||url.contains("/ueditor/")
) {
//放行
chain.doFilter(request, response);
}else{
//不放行,去登录
resp.getWriter().write("<script>window.parent.location.href=\"/web/login.html\";</script>");
}
}
}
登出系统
常见坑点
JSON反序列化时 日期类型转换问题