前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springmvc响应Ajax请求(@ResponseBody)

Springmvc响应Ajax请求(@ResponseBody)

原创
作者头像
爱撒谎的男孩
发布2018-05-10 18:41:47
9.6K5
发布2018-05-10 18:41:47
举报
文章被收录于专栏:码猿技术专栏码猿技术专栏

Springmvc响应Ajax请求(@ResponseBody)

创建工程

  • 创建maven project
  • 选择war
  • 自动生成web.xml
  • Target Runtime 选择 Tomcat
  • 添加依赖pom.xml
代码语言:javascript
复制
<dependencies>
​
        <!-- SpringMVC -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>3.2.8.RELEASE</version>
        </dependency>
        
        <!-- Spring-JDBC,要和spring-webmvc的版本一致 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>3.2.8.RELEASE</version>
        </dependency>
​
        <!-- MyBatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
​
        <!-- MyBatis-Spring 整合jar包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.3.2</version>
        </dependency>
        
        <!-- MySQL -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.28</version>
        </dependency>
​
        <!-- DBCP -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>
​
        <!-- Junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
​
    </dependencies>
  • 配置前端控制器和解决中乱码的过滤器(web.xml)
代码语言:javascript
复制
<!--配置中文乱码的过滤器-->
<filter>
        <filter-name>CharacterEncodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
​
    <filter-mapping>
        <filter-name>CharacterEncodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
​
<!--配置前端控制器-->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <!--加载spring配置文件-->
            <param-value>classpath:spring-*.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
​
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
  • 配置spring-mvc.xml
    • 要想使用@ResponseBody这个注解来接收Ajax发送过来的请求,必须加上注解驱动<mvc:annotation-driven></mvc:annotation-driven>
代码语言:javascript
复制
    <!-- 组件扫描 -->
    <context:component-scan 
        base-package="cn.tedu.spring.controller" />
    
    <!-- 配置ViewResolver -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/web/" />
        <property name="suffix" value=".jsp" />
    </bean>
    
    <!-- 配置注解扫描,用于ajax的注解扫描 -->
    <mvc:annotation-driven></mvc:annotation-driven>

编写前端表单

  • 其实并不是使用表单提交的,可以不使用表单
代码语言:javascript
复制
<form action="" method="post">
    姓名: <input type="text" name="name" id="name" onblur="checkName()"><span id="nameSpan"></span><br>
    密码:<input type="password" name="pwd" id="pwd"><span id="pwSpan"></span><br>
    <input type="submit" value="注册">
</form>

效果和实现(@RequestBody)

用户名文本框失去焦点,异步检测用户

  • 用户名文本框失去焦点发生请求处理方法,检测用户名
    • 请求方式POST
    • 返回的值不再是视图的名称,而是处理请求的结果,即使返回给Ajax请求的数据
代码语言:javascript
复制
    @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请求
代码语言:javascript
复制
<!-- 添加jquery文件 -->
<script type="text/javascript" src="<%=request.getContextPath() %>/web/jquery-3.2.1.min.js"></script>
​
<script type="text/javascript">
    
    function checkName(){
        var name=$("#name").val(); //获取用户名
        if(name==""){
            alert("用户名不能为空");
            return;
        }
        var url="<%=request.getContextPath()%>/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"); 
                }
            }
        })
    }`
​
</script>
  • 使用javascript发出Ajax请求
    • GET请求 :xhr.open("GET","<%=request.getContextPath()%>/user/checkName.do?name="+name,true);
    • POST请求需要将数据封装到xhr.send(data)
代码语言:javascript
复制
//使用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","<%=request.getContextPath()%>/user/checkName.do",true);
    //在open之后,send之前添加请求头信息
    xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
    //在send之中添加请求信息
    xhr.send("name="+name);  //发送请求
}

@ResponseBody

  • 配置注解驱动支持该注解的使用,直接在spring-mvc.xml中配置即可<mvc:annotation-driven></mvc:annotation-driven>
  • 添加jackson的依赖,处理json数据
    • 我们需要三个jar包,我们只需要添加jackson-databind即可,就会自动的导入其他的两个

代码语言:javascript
复制
    <!-- 添加jackson -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.9.4</version>
        </dependency>
  • 用于响应Ajax请求
  • 使用@ResponseBody标记的Controller方法的返回值,不再是返回的视图名称,而是返回的给Ajax的请求结果,可以是StringList,Map,单个对象

返回单个值

  • 返回的单个值,比如Stringintboolean
  • 直接使用上面的例子即可
代码语言:javascript
复制
    @RequestMapping("/checkName.do")
    @ResponseBody   //使用@ResponseBody,表示这个是处理ajax的请求
    public String checkName(@RequestParam("name")String name){
        if ("admin".equals(name)) {
            return "0";  //表示admin这个用户名不能使用,已经存在
        }
        return "1";  //表示此时的用户名不存在,可以使用
    }

返回Map

  • 这里我们返回的是一个Map<String,Object>
  • 使用了JackSon,spring会将Map自动转换成JSON对象,那么我们在JSP中就可以用JSON来获取数据即可
  • 编写Controller方法,使用@ResponseBody注解
代码语言:javascript
复制
    @RequestMapping("/testMap.do")
    @ResponseBody   //使用注解
    public Map<String,Object> testMap(@RequestParam("name")String name,@RequestParam("age")Integer age){
        System.out.println(name+"---"+age); //接收请求参数
        Map<String, Object> map=new HashMap<String, Object>();  //新建一个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中的值
代码语言:javascript
复制
//Ajax请求testMap.do
function testMap(){
    var url="<%=request.getContextPath()%>/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<Object>
  • JackSon会自动将List转换成JSON数组,在JSP页面就可以使用JSON的方式来获取数据
  • 比如:[{"name":"JACK","age":22},{"name":"Tom","age":33},10],这个是一个JSON数组的形式,因此我们在js中需要遍历这个数组
  • Controller中方法如下:
代码语言:javascript
复制
    @RequestMapping("/testList.do")
    @ResponseBody
    public List<User> testList(@RequestParam("name") String name,
            @RequestParam("age") Integer age) {
        System.out.println(name + "---" + age); // 接收请求参数
        List<User> list = new ArrayList<User>();
        // 新建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请求
    • 此时返回的是数组,因此需要循环遍历
代码语言:javascript
复制
//Ajax请求testList.do
function testList(){
    var url="<%=request.getContextPath()%>/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<responseData.length;i++){
                //将数据输出到控制台
                console.log(responseData[i].name+"----->" + responseData[i].age);
            }
        }
    })
}

返回单个对象

  • 返回的是一个对象,比如一个User对象,JackSon会将其转换成为JSON对象返回给浏览器
  • 返回的是对象,那么我们在js中可以直接使用key-value的形式取出其中的值
  • Controller中的方法
代码语言:javascript
复制
    @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请求,并且接收数据
    • 直接使用取值即可
代码语言:javascript
复制
//Ajax请求testObject.do
function testObject(){
    var url="<%=request.getContextPath()%>/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);
        }
    })
}

练习

省市二级菜单联动

  • 前端使用下拉菜单<select>实现
    1. 加载页面完成之后,发送一个异步请求,请求所有的省份,在省的下拉菜单中显示出来
    2. 当用户选择了某个省之后,那么发送一个异步请求,获取当前省的所有的信息,并且显示在市的下拉菜单中
    3. 的下拉菜单中需要使用onchange监听选项的改变,只要选项改变了就要发出异步请求,返回对应城市的信息
代码语言:javascript
复制
省:<select name="province" id="province" onchange="getCity()">
    <option value="-1">请选择省</option>
</select>
​
​
市:<select name="city" id="city">
    <option value="-1">请选择市</option>
</select>
​
<!--加载jquery-->
<script type="text/javascript" src="<%=request.getContextPath() %>/web/jquery-3.2.1.min.js"></script>
​
<script type="text/javascript">
    //只要页面加载完成之后就会执行其中的逻辑
    $(function(){
        getProvince();   //页面加载完成就调用这个方法发出异步请求
        
    });
    
    //获取省份的方法
    function getProvince(){
        var url="<%=request.getContextPath()%>/menu/getProvince.do";  //异步请求的url
        var d={};   //没有数据提交
        $.post(url,d,function(data,status,xhr){
            if(status=="success"){
                //循环遍历返回的JSON数组
                for(var i=0;i<data.length;i++){
                    //创建option,用于插入节点
                    var option="<option value=" + data[i].code + ">"+data[i].name+"</option>";
                    //将option插入到下拉列表中
                    $("#province").append(option);
                }
            }
        }); 
    }
    
    
    //根据选择的省份获取市
    function getCity(){
        var province=$("#province").val();  //获取下拉菜单的值,这里返回的是省份的编号
        var url="<%=request.getContextPath()%>/menu/getCity.do";  //异步请求的url
        var d={"province":province};   //将省份的编号传入
        
        //每次都要清空之前的城市
        $("#city").html("<option value='-1'>请选择市</option>");
        
        //如果用户点击了请选择省,那么返回的值就是-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<data.length;i++){
                    //创建option,用于插入节点
                    var option="<option value=" + data[i].code + ">"+data[i].name+"</option>";
                    //将option插入到下拉列表中
                    $("#city").append(option);
                }
            }
        }); 
    }
</script>
  • Controller编写方法
    1. 展示页面的方法(showMenu.do)
    2. 返回省份信息的方法
    3. 返回城市信息方法
代码语言:javascript
复制
    //显示页面
    @RequestMapping("/showMenu.do")
    public String showMenu() {
        return "menu";
    }
    
    //异步请求返回省份的信息
    @RequestMapping("/getProvince.do")
    @ResponseBody
    public List<Province> getProvince(){
        Province p1=new Province();
        p1.setName("江苏");
        p1.setCode(1001);
        
        Province p2=new Province();
        p2.setName("山东");
        p2.setCode(1002);
        
        List<Province> provinces=new ArrayList<Province>();
        provinces.add(p1);
        provinces.add(p2);
        return provinces;
    }
    
    //异步获取城市信息的方法,这里没有操作数据库,仅仅是模拟,因此只要返回数据即可
    @RequestMapping("/getCity.do")
    @ResponseBody
    public List<City> getCity(@RequestParam("province") Integer code){
        System.out.println(code);
        List<City> cities=new ArrayList<City>();
        
        /**
         * 如果这里涉及到数据库操作
         *      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<City>集合
         */
        
        //这里省略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的读取方式获取返回的数据即可

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Springmvc响应Ajax请求(@ResponseBody)
    • 创建工程
      • 编写前端表单
        • 效果和实现(@RequestBody)
          • 用户名文本框失去焦点,异步检测用户
        • @ResponseBody
          • 返回单个值
          • 返回Map
          • 返回List
          • 返回单个对象
        • 练习
          • 省市二级菜单联动
        • 总结
        相关产品与服务
        云数据库 MySQL
        腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档