day56_springmvc

今日内容

零、 复习昨日

零、 复习昨日

一、JSON处理【重点】

springmvc支持json数据交互,但是自己本身没有对应jar,使用的是第三方Jackson,只需要导入对应依赖,springmvc即可使用


如果需要换用到FastJson

  • 导入依赖
  • 配置文件中指定json转换的类型为FastJson
  • 本次课程没有替换,用的还是Jackson
    
    <dependency>
      <groupId>com.fasterxml.jackson.coregroupId>
      <artifactId>jackson-databindartifactId>
      <version>2.9.8version>
    dependency>

1.1 响应JSON数据

只需要在方法上加@ResponseBody注解,即可将返回值变为JSON

需求: 前端发请求,后台响应给浏览器JSON

@Controller
public class JSONController {

    @RequestMapping("/test1")
    @ResponseBody // 返回JSON对象,不经过视图解析器
    public String test1() {
        System.out.println("响应json-test1" );
        return "{\"code\":200,\"msg\":\"OK\"}";
    }
}

前后端交互,一般固定一个JSON模板

模板一般要包含三个信息:

  • 状态码

    • 自定义的
    • 每个意思都不一样
    • 假如: 20000 成功 40000 资源未找到 50000 没有权限 60000 代码异常…
  • 提示信息

  • 数据

    {
    	code:20000,
    	msg:"查询成功",
        data:{
            id:1,
            username:"张三"
        }
    }
    
/**
 * --- 天道酬勤 ---
 *
 * @author QiuShiju
 * @desc 封装的结果数据
 * --> 符合layui默认模板格式
 * {
 *   "code": 0,
 *   "msg": "",
 *   "count": 1000,
 *   "data": [{}, {}]
 * }
 */
public class ResultData {

    private int code; // 0是成功,其他都是不成功
    private String msg;
    private int count;
    private Object data;

    public ResultData() {
    }

    public static ResultData ok() {
        ResultData resultData = new ResultData( );
        resultData.setCode(0);
        resultData.setMsg("成功");
        return resultData;
    }

    public static ResultData ok(Object data) {
        ResultData resultData = new ResultData( );
        resultData.setCode(0);
        resultData.setMsg("成功");
        resultData.setData(data);

        return resultData;
    }

    public static ResultData ok(Object data,int count) {
        ResultData resultData = new ResultData( );
        resultData.setCode(0);
        resultData.setMsg("成功");
        resultData.setData(data);
        resultData.setCount(count);
        return resultData;
    }

    public static ResultData fail() {
        ResultData resultData = new ResultData( );
        resultData.setCode(-1);
        resultData.setMsg("失败");
        return resultData;
    }
   // set get 省略,自己加
}

Controller方法只需要将返回值类型变为对应的类型

    @RequestMapping("/test2")
    @ResponseBody // 返回JSON对象,不经过视图解析器
    public ResultData test2() {
        System.out.println("响应json-test2" );
        return ResultData.ok();
    }

    @RequestMapping("/test3")
    @ResponseBody
    public ResultData test3() {
        System.out.println("响应json-test3" );
        // 模拟查询全部
        List<User> list = new ArrayList<>( );
        for (int i = 1; i < 10; i++) {
            User user = new User( );
            user.setId(i);
            user.setUsername("测试"+i);
            user.setScore(i * 33.3);
            user.setBirthday(new Date(i * 24 * 60 * 60 * 1000));

            list.add(user);
        }
        return ResultData.ok(list);
    }

如果类中所有方法都需要返回成JSON,即都要加@ResponseBody,那么就可以将类上加@ResponseBody,方法上不需要加注解


其实还有一个类似的注解@RestController,相对于是@Controller和@ResponseBody综合版

这是RESTful开发风格的写法

1.2 接收JSON数据

1.2.1 简单类型

前端使用ajax发送json数据,后端使用简单类型(基本类型,String,Date)来直接接收

<button id="btn1">btn1-ajax-json-简单类型button>
<script src="/js/jquery-2.1.0.js">script>
<script>
    $("#btn1").click(function (){
        $.ajax({
            url:"/test4.do",
            type:"get",
            data:{"id":1,"username":"张三"},
            success:function (ret){
                if (ret.code == 0){
                    alert(ret.msg)
                }
            },
            error:function (){
                alert("服务器正忙!")
            }
        })
    });
script>
    /**
     * 接收JSON数据
     */
    @RequestMapping("/test4")
    public ResultData test4(int id,String username){
        System.out.println("id = " + id);
        System.out.println("username = " + username);
        return ResultData.ok();
    }

1.2.2 对象类型

前端使用ajax发送json数据,后端使用对象来接收

【特别注意】: 其实真正发送数据到后台时是按照表单内容发送,所以后端可以直接用对象接收! 为什么data为json格式的数据,还是会以表单内容发送呢?

是因为ajax的contentType默认是application/x-www-form-urlencoded


即,如果真的要发送完全的JSON数据,就需要指定contentType="application/json",但是此时后台就没有办法直接使用对象接收数据


【总结】:

  • 请求方式是GET的话,contentType指定成什么类型,后台都可以直接用对象接收

  • 请求方式是POST的,contentType=“application/x-www-form-urlencoded”(默认),后台也可以使用对象接收

  • 前端ajax请求方式是POST的,contentType="application/json"时,发送的数据data内容需要变成json字符串才行,否则后台就不能使用对象直接接收,需要使用@RequestBody来解析JSON

data:JSON.stringify({“id”:1,“username”:“admin”})

<button id="btn2">btn2-ajax-json-对象类型button>
<script src="/js/jquery-2.1.0.js">script>
<script>
    $("#btn2").click(function (){
        $.ajax({
            url:"/test5.do",
            type:"post",
            data:{"id":1,"username":"张三","score":98.0,"birthday":"2022-12-12"},
            // contextType:"application/json",
            success:function (ret){
                if (ret.code == 0){
                    alert(ret.msg)
                }
            },
            error:function (){
                alert("服务器正忙!")
            }
        })
    });
script>
public class User {

    private int id;
    private String username;
    private double score;
    
    // 日期,默认只能解析yyyy/MM/dd类型的日期,如果前端就是yyyy-MM-dd
    // 那么就需要使用该注解
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    // set get...
}
    @RequestMapping("/test5")
//  后台直接使用User对象来接收,JSON的key要与User的属性一致
    public ResultData test5(User user){
        System.out.println("user = " + user);
        return ResultData.ok();
    }

1.2.3 总结

  • 前端发送json数据,后台如果使用简单类型接收单独参数,正常接收

  • 前端发送json数据,后台如果使用对象接收,可以尝试使用对象直接接收

  • 如果对象内没有数据,可以使用@RequestBody来解析json,将数据封装到对象

二、文件上传

2.1 图片上传

使用第三方(commons-io,commons-fileupload)依赖

    
    <dependency>
      <groupId>commons-iogroupId>
      <artifactId>commons-ioartifactId>
      <version>2.4version>
    dependency>
    
    <dependency>
      <groupId>commons-fileuploadgroupId>
      <artifactId>commons-fileuploadartifactId>
      <version>1.3.3version>
      
      <exclusions>
        <exclusion>
          <groupId>javax.servletgroupId>
          <artifactId>servlet-apiartifactId>
        exclusion>
      exclusions>
    dependency>

springmvc配置文件上传解析器


<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    
    <property name="maxUploadSize" value="102400"/>
bean>

页面


<form action="/upload.do" method="post" enctype="multipart/form-data">
    文件上传<input type="file" name="source"><br>
    <input type="submit" value="上传">
form>

后端

   /**
     * 文件上传(存储到tomcat服务)
     * @param source 类型必须是MultipartFile,参数名必须是和前端name值一样
     *               这样,文件上传时,MultipartFile内部就会有文件对象
     * @param request 通过请求对象可以获得服务器地址,后续讲图片上传到服务对应位置
     * @return
     */
    @RequestMapping("/upload")
    public String upload(MultipartFile source, HttpServletRequest request) throws IOException {
        String originalFilename = source.getOriginalFilename( );
        System.out.println("originalFilename = " + originalFilename);

        // 产生随机图片名
        String prefix = UUID.randomUUID( ).toString( );
        System.out.println("prefix = " + prefix);

        // 获得文件后缀
        String suffix = FilenameUtils.getExtension(originalFilename);

        // 组合成新文件名
        String filename = prefix+"."+suffix;

        // 获得服务器路径
        String realPath = request.getServletContext( ).getRealPath("/upload_file");
        System.out.println("realPath = " + realPath);

        // 创建文件夹
        File parentFile = new File(realPath);
        if (!parentFile.exists()) {
            parentFile.mkdir();
        }

        // 开始上传
        source.transferTo(new File(parentFile,filename));

        return "ok";
    }

2.2 上传后回显

方案一(同步): 上传成功后,将图片路径返回给前端,前端再处理

方案二(异步): 使用ajax上传,上传成功后,将图片路径返回给ajax的回调函数

前端页面

<h1>上传图片并回显h1>

<form id="formData">
    文件上传<input type="file" name="source"><br>
    <input type="button" onclick="ajaxUpload()" value="上传">
form>

<img width="300px" id="img" src="" alt="图片">

<script src="/js/jquery-2.1.0.js">script>
<script>
    // 文件上传
    function ajaxUpload(){
        // 获得表单对象
        var formData = new FormData($("#formData")[0]);
        // 使用ajax文件上传
        $.ajax({
            url:"/upload.do",
            type:"post",
            data:formData,
            async:false,
            cache:false,
            contentType:false,
            processData:false,
            success:function (ret) {
                if (ret.code == 0) {
                    console.log(ret.data)
                    $("#img").attr("src",ret.data);
                }else{
                    alert("上传失败1");
                }
            },
            error:function () {
                alert("上传失败2");
            }
        });
    }
script>
body>
html>

后端

        // 与之前一样,只是将图片路径返回了,JSON格式的数据
        return ResultData.ok("/upload_file/"+filename);

2.3 上传文件后续

1 将来写项目,文件上传后,要将图片路径存储到数据库

2 等真正写项目时,一般要有文件服务器(阿里云OSS,七牛云存储等)

三、文件下载

前端

<div>
  <div>
      
    <img width="300px" src="/upload_file/81d30e55-d6ca-4463-ba3b-5732504128f3.jpg">
      <button>
          
          <a href="/download.do?filename=81d30e55-d6ca-4463-ba3b-5732504128f3.jpg">下载a>
      button>
  div>
  <div>
    <img width="300px" src="/upload_file/dazhong.jpg">
      <a href="/download.do?filename=dazhong.jpg">下载a>
  div>
div>

后端

/**
     * 下载图片
     * 下载是需要响应一个对话框,选择文件下载到什么地方
     * 不需要跳转页面,或者返回JSON
     */
@RequestMapping("/download")
public void download(String filename, HttpServletRequest request, HttpServletResponse response) throws IOException {

    String realPath = request.getServletContext( ).getRealPath("/upload_file");
    String filepath = realPath+"/"+filename;

    //设置响应头 告知浏览器,要以附件的形式保存内容
    //浏览器显示的下载文件名
    response.addHeader("content-disposition","attachment;filename="+filename);
    response.setContentType("multipart/form-data");
    //读取目标文件,写出给客户端
    IOUtils.copy(new FileInputStream(filepath),response.getOutputStream());
}

四、SSM

在Spring整合Mybatis基础上,再加上SpringMVC的配置即可

依赖

  • spring核心依赖
  • AOP依赖
  • web,webmvc依赖
  • mybatis,数据库驱动,数据源,spring-jdbc,
  • mybatis-spring
  • log4j
  • Servlet-api
  • jackson
  • 注意lombok版本不要太高,1.16即可

配置文件

  • applicationContext.xml
  • springmvc.xml
  • mybatis-config.xml
  • lo4j.properties
  • db.properties
  • web.xml
  • 注意路径问题,需要加classpath:

1 web.xml定义监听器


<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListenerlistener-class>
listener>

<context-param>
    <param-name>contextConfigLocationparam-name>
    <param-value>classpath:applicationContext.xmlparam-value>
context-param>

2 springmvc和applicationContext.xml

springmvc.xml



<context:component-scan base-package="com.qf" use-default-filters="false">
    
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>

applicationContext.xml



<context:component-scan base-package="com.qf">
    
    <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
context:component-scan>

五、作业

1 完成ssm整合,完成查询全部,分页模糊查询
2 复习mybatis ,复习项目

你可能感兴趣的:(#,Java2307,java,spring,mybatis)