Springmvc响应Ajax请求(@ResponseBody)
创建工程创建maven project
选择war包
自动生成web.xml
Target Runtime 选择 Tomcat
添加依赖pom.xml
org.springframework
spring-webmvc
3.2.8.RELEASE
org.springframework
spring-jdbc
3.2.8.RELEASE
org.mybatis
mybatis
3.4.6
org.mybatis
mybatis-spring
1.3.2
mysql
mysql-connector-java
5.1.28
commons-dbcp
commons-dbcp
1.4
junit
junit
4.12
配置前端控制器和解决中乱码的过滤器(web.xml)
别急,还有后续,需要加入架构师技术交流群或者想要更多Java干货、架构师视频课程的可以联系我,点一下chenjiabing666.github.io
CharacterEncodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
utf-8
CharacterEncodingFilter
/*
SpringMVC
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:spring-*.xml
1
SpringMVC
*.do
配置spring-mvc.xml要想使用@ResponseBody这个注解来接收Ajax发送过来的请求,必须加上注解驱动
base-package="cn.tedu.spring.controller" />
编写前端表单其实并不是使用表单提交的,可以不使用表单
姓名:
密码:
效果和实现(@RequestBody)
用户名文本框失去焦点,异步检测用户用户名文本框失去焦点发生请求处理方法,检测用户名请求方式POST
返回的值不再是视图的名称,而是处理请求的结果,即使返回给Ajax请求的数据
@RequestMapping("/checkName.do")
@ResponseBody //使用@ResponseBody,表示这个是处理ajax的请求 public String checkName(@RequestParam("name")String name){
if ("admin".equals(name)) {
return "0"; //表示admin这个用户名不能使用,已经存在 }
return "1"; //表示此时的用户名不存在,可以使用 }
前端编写Ajax请求(JQUERY)使用JQuery中的Ajax请求
function checkName(){
var name=$("#name").val(); //获取用户名 if(name==""){
alert("用户名不能为空");
return;
}
var url="/user/checkName.do"; // 请求的url $.post(url,{'name':name},function(responseData,status,xhr){
//如果状态码正确 if(status=="success"){
if(responseData=="0"){
//为节点添加提示内容 $("#nameSpan").text("用户名已经存在,请重新输入");
$("#nameSpan").css("color","red"); //设置颜色为红色 }else{
$("#nameSpan").text("用户名不存在,可以使用");
$("#nameSpan").css("color","green");
}
}
})
}`
使用javascript发出Ajax请求GET请求 :xhr.open("GET","/user/checkName.do?name="+name,true);
POST请求需要将数据封装到xhr.send(data)中
//使用POST请求function checkNameFun(){
var xhr=getXHR(); //获取XHR //监听状态改变 xhr.onreadystatechange=function(){
if(xhr.readyState==4&&xhr.status==200){
var text=xhr.responseText; //获取返回的数据 if(Text=="0"){
alert("用户名已经存在,请重新输入");
}else{
alert("用户名不存在,可以使用");
}
}
}
var name=$("#name").val(); //获取name文本框中的值 if(name==""){
alert("用户名不能为空");
return;
}
//编写请求 xhr.open("POST","/user/checkName.do",true);
//在open之后,send之前添加请求头信息 xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
//在send之中添加请求信息 xhr.send("name="+name); //发送请求}
@ResponseBody配置注解驱动支持该注解的使用,直接在spring-mvc.xml中配置即可
添加jackson的依赖,处理json数据我们需要三个jar包,我们只需要添加jackson-databind即可,就会自动的导入其他的两个
com.fasterxml.jackson.core
jackson-databind
2.9.4
用于响应Ajax请求
使用@ResponseBody标记的Controller方法的返回值,不再是返回的视图名称,而是返回的给Ajax的请求结果,可以是String,List,Map,单个对象等
返回单个值返回的单个值,比如String,int,boolean
直接使用上面的例子即可
@RequestMapping("/checkName.do")
@ResponseBody //使用@ResponseBody,表示这个是处理ajax的请求 public String checkName(@RequestParam("name")String name){
if ("admin".equals(name)) {
return "0"; //表示admin这个用户名不能使用,已经存在 }
return "1"; //表示此时的用户名不存在,可以使用 }
返回Map这里我们返回的是一个Map
使用了JackSon,spring会将Map自动转换成JSON对象,那么我们在JSP中就可以用JSON来获取数据即可
编写Controller方法,使用@ResponseBody注解
@RequestMapping("/testMap.do")
@ResponseBody //使用注解 public Map testMap(@RequestParam("name")String name,@RequestParam("age")Integer age){
System.out.println(name+"---"+age); //接收请求参数 Map map=new HashMap(); //新建一个Map //新建User对象 User user1=new User();
user1.setName("JACK");
user1.setAge(22);
User user2=new User();
user2.setAge(33);
user2.setName("Tom");
//将上面的User对象添加到map中 map.put("u1",user1);
map.put("u2",user2);
return map;
}
在jsp页面中添加一个方法,用于发出Ajax请求使用返回的数据(JSON对象),直接使用data.key的形式即可取出Map中的值
//Ajax请求testMap.dofunction testMap(){
var url="/user/testMap.do"; // 请求的url var d={'name':'陈加兵','age':22}; //需要发出请求的参数 $.post(url,d,function(responseData,status,xhr){
//如果状态码正确 if(status=="success"){
var user1=responseData.u1; //取出key为u1的值,是一个user对象 var user2=responseData.u2; //取出key为u2的值,是一个user对象 alert("u1 = "+user1.name+"---"+user1.age); //打印出u1中的name,age的值 }
})
}
返回List这里的返回值是List
JackSon会自动将List转换成JSON数组,在JSP页面就可以使用JSON的方式来获取数据
比如:[{"name":"JACK","age":22},{"name":"Tom","age":33},10],这个是一个JSON数组的形式,因此我们在js中需要遍历这个数组
Controller中方法如下:
@RequestMapping("/testList.do")
@ResponseBody
public List testList(@RequestParam("name") String name,
@RequestParam("age") Integer age) {
System.out.println(name + "---" + age); // 接收请求参数 List list = new ArrayList();
// 新建User对象 User user1 = new User();
user1.setName("JACK");
user1.setAge(22);
User user2 = new User();
user2.setAge(33);
user2.setName("Tom");
//将数据添加到其中 list.add(user1);
list.add(user2);
return list;
}
jsp中使用发出Ajax请求此时返回的是数组,因此需要循环遍历
//Ajax请求testList.dofunction testList(){
var url="/user/testList.do"; // 请求的url var d={'name':'陈加兵','age':22}; //需要发出请求的参数 $.post(url,d,function(responseData,status,xhr){
//如果状态码正确 if(status=="success"){
//此时返回的是一个数组,因此我们需要循环遍历这个数组,但是其中的元素是一个User对象,因此可以使用key-value的形式取出其中的值 for(var i=0;i
//将数据输出到控制台 console.log(responseData[i].name+"----->" + responseData[i].age);
}
}
})
}
返回单个对象返回的是一个对象,比如一个User对象,JackSon会将其转换成为JSON对象返回给浏览器
返回的是对象,那么我们在js中可以直接使用key-value的形式取出其中的值
Controller中的方法
@RequestMapping("/testObject.do")
@ResponseBody
public User testObject(@RequestParam("name") String name,
@RequestParam("age") Integer age) {
System.out.println(name + "---" + age); // 接收请求参数 User user=new User();
user.setName("JACK");
user.setAge(22);
return user;
}
发出Ajax请求,并且接收数据直接使用取值即可
//Ajax请求testObject.dofunction testObject(){
var url="/user/testObject.do"; // 请求的url var d={'name':'陈加兵','age':22}; //需要发出请求的参数 $.post(url,d,function(responseData,status,xhr){
//如果状态码正确 if(status=="success"){
console.log(responseData.name+"----"+responseData.age);
}
})
}
练习
省市二级菜单联动前端使用下拉菜单实现加载页面完成之后,发送一个异步请求,请求所有的省份,在省的下拉菜单中显示出来
当用户选择了某个省之后,那么发送一个异步请求,获取当前省的所有市的信息,并且显示在市的下拉菜单中
在省的下拉菜单中需要使用onchange监听选项的改变,只要选项改变了就要发出异步请求,返回对应城市的信息
省:
请选择省
市:
请选择市
//只要页面加载完成之后就会执行其中的逻辑 $(function(){
getProvince(); //页面加载完成就调用这个方法发出异步请求
});
//获取省份的方法 function getProvince(){
var url="/menu/getProvince.do"; //异步请求的url var d={}; //没有数据提交 $.post(url,d,function(data,status,xhr){
if(status=="success"){
//循环遍历返回的JSON数组 for(var i=0;i
//创建option,用于插入节点 var option=""+data[i].name+"";
//将option插入到下拉列表中 $("#province").append(option);
}
}
});
}
//根据选择的省份获取市 function getCity(){
var province=$("#province").val(); //获取下拉菜单的值,这里返回的是省份的编号 var url="/menu/getCity.do"; //异步请求的url var d={"province":province}; //将省份的编号传入
//每次都要清空之前的城市 $("#city").html("请选择市");
//如果用户点击了请选择省,那么返回的值就是-1,此时不需要发出异步请求 if(province==-1){
return;
}
//发出异步请求 $.post(url,d,function(data,status,xhr){
if(status=="success"){
//如果返回的是一个空的,直接返回即可,不需要后续的操作 if(data.lengt==0){
return;
}
//循环遍历返回的JSON数组 for(var i=0;i
//创建option,用于插入节点 var option=""+data[i].name+"";
//将option插入到下拉列表中 $("#city").append(option);
}
}
});
}
在Controller编写方法展示页面的方法(showMenu.do)
返回省份信息的方法
返回城市信息方法
//显示页面 @RequestMapping("/showMenu.do")
public String showMenu() {
return "menu";
}
//异步请求返回省份的信息 @RequestMapping("/getProvince.do")
@ResponseBody
public List getProvince(){
Province p1=new Province();
p1.setName("江苏");
p1.setCode(1001);
Province p2=new Province();
p2.setName("山东");
p2.setCode(1002);
List provinces=new ArrayList();
provinces.add(p1);
provinces.add(p2);
return provinces;
}
//异步获取城市信息的方法,这里没有操作数据库,仅仅是模拟,因此只要返回数据即可 @RequestMapping("/getCity.do")
@ResponseBody
public List getCity(@RequestParam("province") Integer code){
System.out.println(code);
List cities=new ArrayList();
/*** 如果这里涉及到数据库操作* 1. 调用service的方法查询,service调用dao的方法查询* 2. dao中的查询: 根据code查询出对应的城市即可,当然是联表查询* 3. select c.name,c.code from city c join province p on c.provice_id=p.id;* 4. mybatis调用第三步的查询语句,直接返回的就是List集合*/
//这里省略if的判断,主要是看效果 City c1=new City();
c1.setName("南京");
c1.setCode(123);
City c2=new City();
c2.setName("淮安");
c2.setCode(1223);
cities.add(c1);
cities.add(c2);
return cities; //返回集合 }
总结springmvc会通过jackson将返回给ajax请求的对象自动封装成JSON对象,那么在JSP页面我们就可以使用JSON的读取方式获取返回的数据即可