项目1在线交流平台-3.开发交流社区核心功能模块-2.发布帖子-AJAX技术

参考牛客网高级项目教程

1. 功能需求

在这里插入图片描述

在这里插入图片描述

  • 1.点击主页中的“我要发布”按钮,弹出异步请求的输入框
  • 2.在输入框中填入要发布的内容,点击提交,可以发布异步请求
  • 3.帖子内容一方面会过滤加工后入库,一方面会向浏览器响应Json数据,显示发布的提示信息
  • 4.发布成功后,会重定向跳转到主页

2. AJAX示例

2.1 JSON回顾

JSON 键值对是用来保存 JavaScript 对象的一种方式,

  • 和 JavaScript 对象的写法也大同小异,
  • 键/值对组合中的键名写在前面并用双引号 “” 包裹,使用冒号 : 分隔,然后紧接着值:

JSON 是 JavaScript 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串

var obj = {a: 'Hello', b: 'World'}; //这是一个对象,注意键名也是可以使用引号包裹的
var json = '{"a": "Hello", "b": "World"}'; //这是一个 JSON 字符串,本质是一个字符串

@ResponseBody 如果想返回js对象,必须有此注解,

  • 在SpringMVC中,有此注解,会将返回类型的map,list等数据结构自动转换为JSON字符串

2.2 FastJson

1)fastjson的特点与作用
  • 虽然X代表XML,但目前JSON的使用比XML更加普遍。
  • fastjson.jar是阿里开发的一款专门用于Java开发的包,
  • 可以方便的实现json对象与JavaBean对象的转换
  • 实现json对象与json字符串的转换
    • 实现json的转换方法很多,最后的实现结果都是一样的。
  • Java对象 -> Json对象->JSON字符串 -> JS对象
2)fastjson 三个主要的类
JSONObject 代表 json 对象
  • JSONObject实现了Map接口, 猜想 JSONObject底层操作是由Map实现的。
  • JSONObject对应json对象通过各种形式的get()方法可以获取json对象中的数据
  • 也可利用诸如size(),isEmpty()等方法获取”键:值”对的个数和判断是否为空。
  • 其本质是通过实现Map接口并调用接口中的方法完成的
【JSONArray 代表 json 对象数组】
  • 内部是有List接口中的方法来完成操作的。
【JSON 代表 JSONObject和JSONArray的转化】
  • JSON类源码分析与使用
  • 仔细观察这些方法,
    • 主要是实现json对象,json对象数组,javabean对象,json字符串之间的相互转化
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class FastJsonDemo {
    public static void main(String[] args) {
        //创建一个对象
        User user1 = new User("1号", 3, "男");
        User user2 = new User("2号", 3, "男");
        User user3 = new User("3号", 3, "男");
        User user4 = new User("4号", 3, "男");
        List<User> list = new ArrayList<User>();
        list.add(user1);
        list.add(user2);
        list.add(user3);
        list.add(user4);
        System.out.println("*******Java对象 转 JSON字符串*******");
        String str1 = JSON.toJSONString(list);
        System.out.println("JSON.toJSONString(list)==>"+str1);
        String str2 = JSON.toJSONString(user1);
        System.out.println("JSON.toJSONString(user1)==>"+str2);
        
        System.out.println("\n****** JSON字符串 转 Java对象*******");
        User jp_user1=JSON.parseObject(str2,User.class);
        System.out.println("JSON.parseObject(str2,User.class)==>"+jp_user1);
        
        System.out.println("\n****** Java对象 转 JSON对象 ******");
        JSONObject jsonObject1 = (JSONObject) JSON.toJSON(user2);
        System.out.println("(JSONObject) JSON.toJSON(user2)==>"+jsonObject1.getString("name"));
        
        System.out.println("\n****** JSON对象 转 Java对象 ******");
        User to_java_user = JSON.toJavaObject(jsonObject1, User.class);
        System.out.println("JSON.toJavaObject(jsonObject1, User.class)==>"+to_java_user);
    }
}
3)FastJson工具方法色设计
引入jar包
<!--	配置fastjson-->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>fastjson</artifactId>
			<version>1.2.58</version>
		</dependency>
给浏览器返回Json字符串信息

在之前设计的CommunityUtil类添加工具方法

JSONObject
  • 封装数据的Json对象,相当于model
  • 添加数据比较方便
map.keySet()
  • 遍历map的每一个key
toJSONString()
  • 将Json对象转为JSON字符串

  • dddd

    **
     * 给浏览器返回Json字符串信息,利用fastjsonAPI,获取json字符串
     * @param code  响应的编码信息
     * @param msg   响应的字符串提示信息
     * @param map   响应的数据
     * @return      Json字符串
     */
    public static String getJSONString(int code, String msg, Map<String, Object> map) {
        JSONObject jsonObject = new JSONObject(); // 封装数据的Json对象,相当于model
        jsonObject.put("code", code);
        jsonObject.put("msg", msg);
        if(map != null) {
            for(String key : map.keySet()) {
                jsonObject.put(key, map.get(key));
            }
        }
        return jsonObject.toJSONString();
    }
    
    // 重载方法
    public static String getJSONString(int code, String msg) {
        return getJSONString(code, msg, null);
    }
    
    public static String getJSONString(int code) {
        return getJSONString(code, null, null);
    }
    
测试
public static void main(String[] args) {
    Map<String, Object> map = new HashMap<>();
    map.put("name", "张三");
    map.put("age", 25);
    System.out.println(getJSONString(0, "提交成功", map));
}
{"msg":"提交成功","code":0,"name":"张三","age":25}

2.3 异步请求

1)AJAX回顾
  • Asynchronous JavaScript and XML
  • 异步的JavaScript与XML,不是一门新技术,只是一个新的术语。
  • 使用AJAX,网页能够将增量更新呈现在页面上,而不需要刷新整个页面
  • 虽然X代表XML,但目前JSON的使用比XML更加普遍
2)jQuery.ajax解析
  • Ajax的核心是XMLHttpRequest对象(XHR)。
    • XHR为向服务器发送请求和解析服务器响应提供了接口。能够以异步方式从服务器获取新数据。
  • jQuery 提供多个与 AJAX 有关的方法
  • 通过 jQuery AJAX 方法,
    • 能够使用 HTTP Get 和 HTTP Post 从远程服务器上请求文本、HTML、XML 或 JSON
    • 同时能够把这些外部数据直接载入网页的被选元素中
  • jQuery 不是生产者,而是大自然搬运工。
  • jQuery Ajax本质就是 XMLHttpRequest,对他进行了封装,方便调用
3)jQuery发送异步请求
HTML中引入JQuery
<script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
定义发送请求按钮,并触发发送方法
<p>
    <input type="button" value="发送" onclick="send();">
</p>
对发送方法的定义
$.post(url,data,回调函数)
  • 使用post请求,需要传三个参数

    • url:即请求路径

    • data:用户输入数据,即要向服务器发送的数据

      • 是JavaScript对象,

        • 可以用js对象表示:

          {name:"李四", age:23}
          
        • 也可以用Json字符串方式表示:

          {"name":"李四", "age":23}
          
    • 回调函数:function (data)

      • 服务器给浏览器响应后,将服务器处理后返回的数据用这个方法返回
        • 数据一般是转成JSON字符串格式给这个方法
$.parseJSON(data)
  • 将字符串转为JS对象

  • 这需要一个标准的JSON字符串,并返回生成的JavaScript对象

  • 通过JS对象,可以快速操作对象中的每个key,value

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>AJAX</title>
    </head>
    <body>
    <p>
        <input type="button" value="发送" onclick="send();">
    </p>
    
    <script src="https://code.jquery.com/jquery-3.3.1.min.js" crossorigin="anonymous"></script>
    <script>
        function send() {
            $.post(
                "/community/alpha/ajax",
                {name:"李四", age:23},
                function (data) {
                    console.log("返回数据类型" + typeof (data))
                    console.log("返回数据:" + data)
    
                    data = $.parseJSON(data);
                    console.log("转换后数据类型" + typeof (data));
                    console.log("code:" + data.code);
                    console.log("提示信息:" + data.msg);
                }
            );
        }
    </script>
    </body>
    </html>
    
4)服务器处理异步请求方法
  • 一般是post请求

  • 会自动识别ajax异步请求中的js数据,将key中的value值接受

  • 最后,使用之前设计的FastJson工具类,生成Json字符串结果

    // ajax示例
    @RequestMapping(path = "/ajax", method = RequestMethod.POST)
    @ResponseBody
    public String testAjax(String name, int age) {
        System.out.println(name); // 可以获取异步请求中的js对象参数值
        System.out.println(age);
        return CommunityUtil.getJSONString(0, "操作成功!");
    }
    

测试结果:

在这里插入图片描述

李四
23

3. 开发发布帖子功能

3.1 dao层处理增加帖子数据

定义接口方法
/**
 * 增加帖子
 */
int insertPosts(DiscussPost discussPost);
定义sql语句
 <!--    定义复用代码块-->   
	<sql id="insertFields">
        insert into discuss_post(user_id, title, content, type, status, create_time, comment_count, score)
          values (#{userId}, #{title}, #{content}, #{type}, #{status}, #{createTime}, #{commentCount}, #{score})
    </sql>
<!--    添加帖子-->
    <insert id="insertPosts" parameterType="discussPost" keyProperty="id">
        <include refid="insertFields"></include>
    </insert>
测试
// 添加帖子
@Test
public void testInsertPosts() {
    DiscussPost discussPost = new DiscussPost();
    discussPost.setContent("你好");
    discussPost.setTitle("测试");
    discussPost.setCreateTime(new Date());
    discussPostMapper.insertPosts(discussPost);
}

在这里插入图片描述

3.2 Service层处理添加帖子业务-过滤

HtmlUtils.htmlEscape
  • HTML格式转义

    public static String htmlEscape(String input) {
        return htmlEscape(input, "ISO-8859-1");
    }
    
将标题、内容转义过滤后再入库
/**
 * 添加帖子业务-要对内容进行过滤
 * @param discussPost
 * @return
 */
public int insertPost(DiscussPost discussPost) {
    // 1.边界处理-先判空
    if(discussPost == null) {
        throw new IllegalArgumentException("参数不能为空!");
    }

    // 2.对标题、帖子内容进行过滤
    // 先进行HTML格式转义
    discussPost.setTitle(HtmlUtils.htmlEscape(discussPost.getTitle()));
    discussPost.setContent(HtmlUtils.htmlUnescape(discussPost.getContent()));
    // 再进行敏感词过滤
    discussPost.setTitle(sensitiveFilter.filter(discussPost.getTitle()));
    discussPost.setContent(sensitiveFilter.filter(discussPost.getContent()));

    // 3.入库
    return discussPostMapper.insertPosts(discussPost);
}

3.3 Controller层处理异步请求

  • 1.先获取当前用户,进行权限判断
  • 2.创建帖子,并调用service层处理
  • 3.返回JSON字符串,先处理成功的,失败的今后统一处理
/**
 * 处理ajax异步发布帖子请求
 * @param title     帖子主题
 * @param content   帖子内容
 * @return          JSON字符串
 */
@RequestMapping(value = "/add", method = RequestMethod.POST)
@ResponseBody
public String addPost(String title, String content) {
    // 1.先获取当前用户,进行权限判断
    User user = hostHolder.getUser();
    if(user == null) {
        return CommunityUtil.getJSONString(403, "您还没登录,无法发布帖子!");
    }
    // 2.创建帖子,并调用service层处理
    DiscussPost discussPost = new DiscussPost();
    discussPost.setTitle(title);
    discussPost.setContent(content);
    discussPost.setUserId(user.getId());
    discussPost.setCreateTime(new Date());
    discussPostService.insertPost(discussPost);

    // 3.返回JSON字符串,先处理成功的,失败的今后统一处理
    return CommunityUtil.getJSONString(0, "发布成功!");
}

3.3 View页面使用JQuery发布异步请求

点击 我要发布 按钮,弹出弹出框
  • 通过设定data-target目标id,对应id弹出框起作用
  • 弹出框:id="publishModal"
  • 提示框:id="hintModal"
    • 提示框中显示的信息:id="hintBody"

注意,没有登录状态,是不能发布的,因此,先检查登录状态

<button type="button" class="btn btn-primary btn-sm position-absolute rt-0" data-toggle="modal" data-target="#publishModal" th:if="${loginUser != null}">我要发布</button>
<!-- 弹出框 -->
<div class="modal fade" id="publishModal" tabindex="-1" role="dialog" aria-labelledby="publishModalLabel" aria-hidden="true">...
<!-- 提示框 -->
<div class="modal fade" id="hintModal" tabindex="-1" role="dialog" aria-labelledby="hintModalLabel" aria-hidden="true">
   <div class="modal-dialog modal-lg" role="document">
      <div class="modal-content">
         <div class="modal-header">
            <h5 class="modal-title" id="hintModalLabel">提示</h5>
         </div>
         <div class="modal-body" id="hintBody">
            发布完毕!
         </div>
      </div>
   </div>
</div>
通过输入框id,在JQuery中输入对应的值
  • 标题:id="recipient-name"
  • 正文:id="message-text"
<form>
   <div class="form-group">
      <label for="recipient-name" class="col-form-label">标题:</label>
      <input type="text" class="form-control" id="recipient-name">
   </div>
   <div class="form-group">
      <label for="message-text" class="col-form-label">正文:</label>
      <textarea class="form-control" id="message-text" rows="15"></textarea>
   </div>
</form>
  • 发布按钮:id="publishBtn"
<div class="modal-footer">
   <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button>
   <button type="button" class="btn btn-primary" id="publishBtn">发布</button>
</div>
  • 提示框中的提示栏:id="hintBody"
<div class="modal-body" id="hintBody">
            发布完毕!
</div>
在js文件中定义异步请求逻辑
<script th:src="@{js/index.js}"></script>
点击发布,会触发发布方法
$(function(){
   $("#publishBtn").click(publish);
});
异步请求方法定义
$("#recipient-name").val()
  • 通过id属性获取输入框中内容
$(“hintBody”).text(data.msg)
  • 将从服务器响应中的数据在提示框中展现
window.location.reload()
  • 刷新页面
function publish() {
   $("#publishModal").modal("hide");  // 点击发布按钮后,弹出框关闭,自动访问服务器处理请求

   // 通过id属性获取标题和内容
   var title = $("#recipient-name").val();
   var content = $("#message-text").val();

   // 发送异步请求(POST)
   $.post(
      CONTEXT_PATH + "/discuss/add",
      {"title":title, "content":content},
      function (data) {  // 回调函数,目的是将提示信息msg在提示框展现出来
         data = $.parseJSON(data);     // 转为js对象,方便取值
         $("hintBody").text(data.msg);  // 将msg值放入提示框中的显示框中
         $("#hintModal").modal("show");    // 提示框展现提示信息
         setTimeout(function(){    // 提示框展现时间设定,2秒后自动隐藏
            $("#hintModal").modal("hide");
             // 刷新页面
				if(data.code == 0) {
					window.location.reload();
				}
         }, 2000);
      }
   )
}

测试结果:

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值