SSM+Ajax实现广告系统

文章目录

1.案例需求

使用SSM+Ajax实现广告系统,包括登录、查询所有、搜索、新增、删除、修改等功能,具体实现的效果图如下:

2.编程思路

  • 登录:
    • 前端处理

      • 使用jQuery的$.ajax方法,在用户点击提交按钮时(阻止表单的默认提交行为),向服务器发送POST请求。请求的URL设置为"login.action",这是Spring MVC中@RequestMapping注解映射的URL。通过data属性将表单中的数据(用户名和密码)以JSON格式发送给服务器。在success回调函数中处理服务器返回的响应数据。
    • 后端处理

      • 使用@RequestMapping("login.action")注解定义处理登录请求的URL。login方法接收前端发送的用户名(advTitle)、密码,以及用于响应的ResponseVO对象和HttpSession对象。调用服务层(advService)的login方法验证用户名和密码。根据验证结果设置ResponseVO对象的code和message属性,并将验证成功的用户信息存入HttpSession中以便后续使用。将ResponseVO对象作为方法的返回值,Spring MVC会自动将其序列化为JSON格式返回给前端。
  • 查询:
    • 前端处理
      • 页面加载时,通过AJAX请求selectCategoryName接口获取所有广告分类的名称,并使用JavaScript动态生成下拉列表()的选项。这样用户就可以在下拉列表中选择广告分类,作为查询条件之一。页面加载后,可能还需要执行一次初始查询,以展示默认的广告信息列表。这可以通过另一个AJAX请求queryInfos.action(不带任何查询参数或使用默认参数)来实现。查询结果通过addRow函数动态添加到表格中。提供一个查询按钮(#btn)或表单提交事件,用于在用户输入查询条件(如广告标题、分类ID)后触发查询操作。点击查询按钮时,阻止表单的默认提交行为,并通过AJAX请求queryInfos.action接口,将查询条件(advTitle和categoryId)作为请求参数发送。接收响应数据后,根据状态码(code)判断查询是否成功,并更新页面内容:如果查询成功,则清空表格并重新添加查询结果;如果查询失败,则显示错误信息。
    • 后端处理
      • 在后端,通过@RequestMapping注解定义了两个查询接口:queryAdvInfos用于根据广告标题(advTitle)和分类ID(categoryId)查询广告信息,queryAdvCategoryNames用于查询所有广告分类的名称。queryAdvInfos方法接收两个参数(advTitle和categoryId),并使用这些参数构建一个查询条件对象(AdvVo),然后调用服务层(advService)的queryAdvsInfo方法执行查询,最后根据查询结果构建响应数据并返回。queryAdvCategoryNames方法直接调用服务层(advCategoryService)的queryAllCategoryNames方法查询所有广告分类的名称,并将结果构建为响应数据返回。对于查询结果,后端使用Map<String, Object>来构建响应数据,其中可能包含状态码(code)、消息信息(INFO或错误信息)、以及查询结果列表(如advInfo_List或advCategoryName_List)。
  • 新增:
    • 前端分析
      • 通过AJAX请求selectCategoryName接口获取广告分类列表,并动态添加到分类选择器中。设置默认过期时间:页面加载时计算下个月的今天作为默认过期时间,并设置到相应的输入框中。使用event.preventDefault()阻止表单的默认提交行为,改为通过AJAX异步提交。创建一个FormData对象,将表单字段和文件数据添加到其中。通过AJAX将FormData对象发送到add.action接口。设置processData和contentType为false,因为FormData对象会自动处理这些设置。根据后端返回的数据显示操作结果,如果添加成功则跳转到广告列表页面。
    • 后端处理
      • 使用@RequestMapping("/add.action")注解定义了一个处理广告添加的HTTP POST请求接口。通过@ResponseBody注解表明该接口返回的数据会直接写入HTTP响应体(body)中,而不是解析为跳转路径或视图名称。接收多个参数,包括HttpServletRequest、MultipartFile(用于文件上传)、广告标题、分类ID、过期时间、广告内容、备注和密码。特别注意MultipartFile用于处理文件上传,其他参数则是普通的表单数据。对过期时间expiredTime进行非空和格式校验,确保用户输入了有效的日期字符串。创建一个临时文件来存储上传的文件,避免直接处理原始输入流可能带来的问题。将上传的文件内容复制到临时文件中,并从临时文件复制到服务器的两个不同位置(可能用于备份或不同的访问路径)。最后,删除临时文件以释放资源。将接收到的数据封装到AdvInfo对象中。调用advService.add(advInfo)方法将广告信息保存到数据库或持久化存储中。根据操作结果返回相应的状态码和信息。
  • 删除:
    • 前端处理:
      • 使用 this.id 获取广告ID,并将其存储在localStorage中,发起一个AJAX POST请求到 "delete.action" URL,携带要删除的广告ID(advId)。在AJAX请求成功后,清空表格体(#myTbody)和消息区域(#msg),并显示服务器返回的消息。如果服务器返回的 code 为200(表示删除成功),则尝试重定向到 "adsList.html" 页面。
    • 后端处理:
      • 接收 advId 和 responseVO 作为参数。调用 advService.deleteAdvById(advId) 来执行删除操作,并根据返回的结果设置 responseVO 的 code 和 message 属性。返回 responseVO 对象。
  • 修改:
    • 前端处理:
      • 通过 localStorage.getItem("advId") 获取要修改的广告的ID。使用AJAX请求到 /queryAdvById.action,传递广告ID作为参数。在AJAX请求的 success 回调中,将返回的广告信息填充到表单的相应字段中。对于下拉选择框,需要遍历选项并设置选中的值。监听修改按钮的点击事件,阻止表单的默认提交行为。使用 FormData 对象收集表单数据,包括文件上传。发起AJAX POST请求到 /update.action,发送 FormData 对象。设置 processData 和 contentType 为 false,以允许发送文件。在AJAX请求的 success 回调中,根据返回的数据显示消息,并在成功时重定向到广告列表页面。
    • 后端处理:
      • 使用 @RequestMapping("/update.action") 注解的方法接收来自前端的POST请求。方法参数包括 HttpServletRequest、MultipartFile(用于文件上传)、以及其他表单字段。从请求中提取广告ID、标题、类别ID、过期时间、内容、备注、密码和文件等参数。对过期时间进行解析,并处理可能的 ParseException 和 NullPointerException。将上传的文件先保存到临时文件中。定义两个目标路径,并将文件从临时文件复制到这两个位置。更新广告对象中的图片路径。删除临时文件。创建一个 AdvInfo 对象,并设置其属性。调用服务层方法 advService.update(advInfo) 来更新数据库中的广告信息。根据服务层方法的返回值,构造一个包含状态码和消息的 Map 对象。使用 @ResponseBody 注解将 Map 对象转换为JSON格式,并发送给前端。

3.案例源码(这里只给出新增部分的Handler和ajax部分,需要详情的可以私信我)

Handler类:

java 复制代码
	@Resource(name = "advServiceImpl")
    private AdvService advService;

    @Resource(name = "advCategoryServiceImpl")
    private AdvCategoryService advCategoryService;
 	@RequestMapping("/add.action")
    @ResponseBody
    public Map<String,Object>  add(HttpServletRequest request, MultipartFile uploadFile,String advTitle, Integer categoryId, String expiredTime, String advContent, String remark,String password) throws IOException, ParseException {

        Map<String,Object> map = new HashMap<>();
        AdvInfo advInfo = new AdvInfo();

        advInfo.setAdvTitle(advTitle);
        advInfo.setCategoryId(categoryId);
        advInfo.setAdvContent(advContent);
        advInfo.setRemark(remark);
        advInfo.setPassword(password);

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date time =null;
        if (expiredTime == null || expiredTime.isEmpty()) {
            throw new IllegalArgumentException("expiredTime cannot be null or empty");
        }
        try {
            time = dateFormat.parse(expiredTime);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }

        advInfo.setExpiredTime(time);

        // 获取Web应用程序的根目录的绝对路径
        String realPath = request.getSession().getServletContext().getRealPath("");

        // 创建临时文件
        File tempFile = null;
        try {
            tempFile = File.createTempFile("upload", ".tmp");
        } catch (IOException e) {
            // 处理异常情况
            e.printStackTrace();
        }

        // 将上传的文件传输到临时文件
        try {
            uploadFile.transferTo(tempFile);
        } catch (IOException e) {
            // 处理异常情况
            e.printStackTrace();
        }

        // 设置图片信息
        String originalFilename = uploadFile.getOriginalFilename();
        advInfo.setImg("images\\" + originalFilename);

        // 定义两个不同的目标路径
        String path1 = realPath + File.separator + "images" + File.separator + originalFilename;

        String path2 = "D:" + File.separator +
                "SoftWare" + File.separator +
                "fs" + File.separator +
                "case" + File.separator +
                "Ajax-advSystem" + File.separator +
                "Ajax-advSystem" + File.separator +
                "src" + File.separator +
                "main" + File.separator +
                "webapp" + File.separator +
                "images"+File.separator + originalFilename;

        // 从临时文件复制到第一个位置
        try {
            FileUtils.copyFile(tempFile, new File(path1));
        } catch (IOException e) {
            // 处理异常情况
            e.printStackTrace();
        }

        // 从临时文件复制到第二个位置
        try {
            FileUtils.copyFile(tempFile, new File(path2));
        } catch (IOException e) {
            // 处理异常情况
            e.printStackTrace();
        }

        // 删除临时文件
        if (tempFile != null && tempFile.exists()) {
            tempFile.delete();
        }


        int result = advService.add(advInfo);
        if (result > 0) {
            map.put("code",200);
            map.put("INFO", "添加广告成功");
        } else {
            map.put("code",100);
            map.put("INFO", "添加广告失败");
        }
        return map;
    }

ajax:

java 复制代码
  $(function () {
    //获取id为empdeptno的元素
    var objselect = document.getElementById("categoryId");
    $.ajax({
      url: "selectCategoryName",
      type: "post",
      success: function (data) {
        for (var i = 0; i < data.advCategoryName_List.length; i++) {
          var advCategoryName = data.advCategoryName_List[i];
          objselect.add(new Option(advCategoryName.categoryName, advCategoryName.categoryId));
        }
      },
      dataType:"json"
    });
  });

  $(function () {
    // 设置过期时间为下个月的今天
    var today = new Date();
    today.setMonth(today.getMonth() + 1); // 设置为下个月
    var expiryDate = today.getFullYear() + '-' +
            ('0' + (today.getMonth() + 1)).slice(-2) + '-' +
            ('0' + today.getDate()).slice(-2); // 格式化为 YYYY-MM-DD

    // 设置输入框的值
    $("#expiredTime").val(expiryDate);

    $("#btn").click(function (event) {
      event.preventDefault();//阻止表单的默认提交行为

      var formdata = new FormData();
      formdata.append("advTitle",$("#advTitle").val());
      formdata.append("categoryId",$("#categoryId").val());
      formdata.append("expiredTime",$("#expiredTime").val());
      formdata.append("advContent",$("#advContent").val());
      formdata.append("remark",$("#remark").val());
      formdata.append("password",$("#password").val());
      formdata.append("uploadFile",document.getElementById("file").files[0]);

      $.ajax({
        url: "add.action",
        type: "post",

        data:formdata,
        processData:false,//发送二进制大数据
        contentType:false,

        success: function (data) {
          $("#mess").html(data.INFO);
          if (data.code == 200) {
            window.location.href = "http://localhost:8080/Ajax_advSystem/adsList.html";
          }
        },
        dataType: "json"
      });
    });
  });

4.小结

  • SSM是指Spring、SpringMVC和MyBatis这三个框架的集合,它们通常一起使用来构建Java Web应用程序。Ajax是一种在无需重新加载整个网页的情况下,能够更新部分网页的技术。
  • SSM框架的重点知识:
    • Spring框架:控制反转(IoC)和依赖注入(DI): 理解如何通过Spring容器管理对象的生命周期和依赖关系。
    • 面向切面编程(AOP): 掌握如何在运行时将横切关注点织入到应用程序中。
    • 事务管理: 理解Spring对事务的支持,包括声明式事务管理。
    • 数据访问: 熟悉Spring的数据访问策略,包括JdbcTemplate和事务管理。
  • SpringMVC框架:
    • MVC架构: 理解模型(Model)、视图(View)和控制器(Controller)的概念和它们在Spring MVC中的实现。
    • 请求处理: 掌握如何通过@Controller和@RequestMapping注解来处理HTTP请求。
    • 数据绑定和验证: 理解如何将请求参数绑定到Java对象,并进行数据验证。
    • 视图解析: 熟悉如何配置视图解析器以及如何返回视图。
  • MyBatis框架:
    • SQL映射: 理解MyBatis如何将SQL语句映射到Java方法上。
    • 配置和映射文件: 掌握MyBatis配置文件和映射文件的编写。
    • 动态SQL: 学会使用MyBatis的动态SQL功能来编写灵活的SQL语句。
    • 插件开发: 了解如何通过MyBatis插件来扩展或增强MyBatis的功能。
  • Ajax的重点知识:
    • XMLHttpRequest对象:创建和使用XMLHttpRequest对象来发送异步请求。
    • 异步请求:理解Ajax的工作原理,包括如何发送请求、处理响应以及更新网页的某部分。
    • 数据格式:熟悉JSON和XML等数据格式,并掌握如何在Ajax中发送和接收这些格式的数据。
    • 事件处理:掌握如何在JavaScript中处理事件,如按钮点击事件,触发Ajax请求。
相关推荐
麒麟而非淇淋1 天前
AJAX 进阶 day4
前端·javascript·ajax
+码农快讯+1 天前
JavaScript 基础 - 第17天_AJAX综合案例
开发语言·javascript·ajax
+码农快讯+1 天前
JavaScript 基础 - 第16天_AJAX入门
javascript·ajax·okhttp
夜月行者1 天前
如何使用ssm实现基于VUE3+SSM框架的在线宠物商城+vue
java·后端·ssm
夜月行者2 天前
如何使用ssm实现企业人事管理系统+vue
java·后端·ssm
小刘|3 天前
Ajax 使用流程详解
前端·javascript·ajax
工业互联网专业3 天前
基于ssm+vue+uniapp的智能停车场管理系统小程序
vue.js·小程序·uni-app·毕业设计·ssm·源码·课程设计
傻虎贼头贼脑4 天前
day19JS-AJAX数据通信
前端·javascript·ajax
aehrutktrjk4 天前
如何从大型语言模型(LLM)流式响应
python·microsoft·ajax·语言模型
wu1113_4 天前
SSMP+ajax实现广告系统的分页效果
java·ajax·maven·mybatis·ssm