Spring Web MVC of Spring Family Bucket (6) - AJAX & Fileupload

Get into the habit of writing together! This is the 9th day of my participation in the "Nuggets Daily New Plan · April Update Challenge", click to view the details of the event .

1. Spring MVC handles AJAX requests

Spring MVC returns JSON formatted data

Copy the spring-mvc-crud project and rename it to spring-mvc-ajax. Spring MVC needs to import jackson-related dependencies to process data in json format

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.13.1</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.13.1</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-annotations</artifactId>
    <version>2.13.1</version>
</dependency>
复制代码

After adding dependencies, put all the JAR packages on the right to the lib folder in the Project Structure -> Artifacts directory and add a new Controller and use the @RestController annotation on the class.

@RestController
public class AnotherController {

    @Autowired
    private EmployeeDao employeeDao;

    @RequestMapping(value = "/list_by_json")
    public Collection<Employee> listByJson(){
        Collection<Employee> all = employeeDao.getAll();
        return all;
    }
}    
复制代码

Restart Tomcat and enter http://localhost:8080/list_by_json in the browser

image.pngAll employee data is displayed in the browser in JSON format

@JsonIgnore

The @JsonIgnore annotation can ignore certain attributes when converting to JSON format data. Add the @JsonIgnore annotation to the Department attribute of the Employee entity class

public class Employee {
   // 其余代码保持不变 
   @JsonIgnore
   private Department department;
}   
复制代码

Restart the application and enter http://localhost:8080/list_by_json in the browser image.png

It can be seen that the Employee data displayed in the browser ignores the Department attribute, and no longer displays the Department attribute information

@JsonFormat

Add the @JsonFormat annotation to specify the format of the output

public class Employee{
    // 其余代码保持不变
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date birth = new Date();
}
复制代码

Restart the application and enter http://localhost:8080/list_by_json image.png in the browser. The format displayed by the time is the format specified by the @JsonFormat annotation, and the default is the timestamp format without the @JSONFormat annotation, as shown in the following figure

image.png

Spring MVC 处理 AJAX 请求

在index.jsp同级目录下新增一个页面emps.jsp,使用ajax请求获取所有员工并显示在页面上

<%@page import="java.util.Date"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
         pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--head标签内容省略-->
<body>
<%=new Date() %>
<a href="${ctp }/list_by_json">ajax获取所有员工</a><br/>

<div>

</div>
<script type="text/javascript">
    $("a:first").click(function(){
        //1、发送ajax获取所有员工
        $.ajax({
            url:"${ctp}/list_by_json",
            type:"GET",
            success:function(data){
                //console.log(data);
                $.each(data,function(){
                    var empInfo = this.lastName+"-->"+this.birth+"--->"+this.gender;
                    $("div").append(empInfo+"<br/>");
                });
            }
        });

        return false;
    });
</script>
</body>
</html>
复制代码

重新启动应用,浏览器输入http://localhost:8080/emps.jsp, 点击页面的超链接,即可获取所有员工的数据 image.png

@RequestBody注解

@RequestBody注解可以直接获得请求体,在AnotherController中增加一个方法postReq,用来处理前端的post请求

@RequestMapping("/post_request")
public String postReq(@RequestBody String user){
    System.out.println("请求体:" + user);
    return "success";
}
复制代码

新增一个页面post.jsp,发送post表单请求到postReq方法

<h2>使用表单发送POST请求</h2>
<div>
    <form action="/post_request" method="post">
        <input name="username" value="stark">
        <input name="password" value="123456">
        <input type="submit">
    </form>
</div>
复制代码

重新启动应用,浏览器进入到http://localhost:8080/post.jsp, 点击提交按钮 image.png 请求提数据被打印在控制台中

在post.jsp页面增加一个ajax的post请求

<h2>使用Ajax发送JSON格式的POST请求</h2>
<a href="/post_request">发送</a>
<script type="text/javascript">
    $("a:first").click(function(){
        var emp = {lastName:"Banner", email:"[email protected]",gender:0};
        var empStr = JSON.stringify(emp);
        //1、发送ajax获取携带JSON格式数据
        $.ajax({
            url:"${ctp}/post_request",
            type:"POST",
            data:empStr,
            contentType: "application/json",
            success:function(data){
                //console.log(data);
                alert(data);
            }
        });

        return false;
    });
</script>
复制代码

浏览器发送http://localhost:8080/post.jsp ,点击发送超链接

image.png 浏览器发送的请求体为JSON格式的数据

image.png @RequestBody注解将JSON格式数据转换成Employee实体类对象

HttpEntity<T>

HttpEntity是指请求和响应的实体类,包含了消息头和消息体,可以从该类中获取请求头请求体以及响应头响应体信息。

在AnotherController中新增一个httpEntity方法,接收一个HttpEntity类为参数

@RequestMapping("/http_entity")
public String httpEntity(HttpEntity<String> str){
    System.out.println(str);
    return "success";
}
复制代码

修改post.jspy页面中的表单的请求地址为/http_entity

<h2>使用表单发送POST请求</h2>
<div>
    <form action="/http_entity" method="post">
        <input name="username" value="stark">
        <input name="password" value="123456">
        <input type="submit">
    </form>
</div>
复制代码

重新启动该应用,浏览器打开post.jsp页面,点击发送按钮发送表单请求

image.png 控制台打印出消息体对象

@ResponseBody、ResponseEntity 与文件下载

该注解会将相应内容放在响应体中

@ResponseBody
@RequestMapping("/hello")
public String hello(){
    return "success";
}
复制代码

访问/ha不会返回success页面,会直接返回字符串success

image.png

还可以自定义响应实体,这要求方法返回ResponseEntity

@RequestMapping("/hallo")
public ResponseEntity<String> hallo(){
    // 定义响应请求头
    MultiValueMap<String, String> headers =new HttpHeaders();
    // 定义响应体
    String body = "<h2>SUCCESS</h2>";
    headers.add("Set-Cookie", "username=stark");
    // 返回响应实体类
    return new ResponseEntity<>(body, headers, HttpStatus.OK);
}
复制代码

重新启动应用,浏览器输入/hallo,页面显示了SUCCESS image.png 自定义的cookie响应码等生效。

ResponseEntity还可以应用到文件下载中,AnotherController方法中新增方法download

@RequestMapping("/download")
public ResponseEntity<byte[]> download(HttpServletRequest request) throws IOException {
    // 1.得到要下载的流
    // 找到要下载文件的真实路径
    ServletContext context = request.getServletContext();
    String realPath = context.getRealPath("/js/jquery-1.9.1.min.js");
    FileInputStream is = new FileInputStream(realPath);
    byte[] tmp = new byte[is.available()];
    is.read(tmp);
    is.close();

    // 2.将要下载的文件返回
    HttpHeaders header = new HttpHeaders();
    header.set("Content-Disposition","attachment;filename="+"jquery-1.9.1.min.js");
    ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(tmp, header, HttpStatus.OK);
    return responseEntity;
}
复制代码

重启tomcat,浏览器输入http://localhost:8080/download, 会自动下载指定的文件

二、文件上传

Spring MVC 为文件上传提供了直接的支持,这种支持是通过即插即用的MultipartResolver实现的,Spring是用Jakarta Commons FileUpload技术实现了一个MultipartResolver的实现类CommonsMultipartResolver

文件上传需要导入commons-fileupload和commons-io两个包,在pom文件中添加依赖

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.4</version>
</dependency>

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.11.0</version>
</dependency>
复制代码

将导入的包放入 lib 文件夹下 image.png

在index.jsp同级目录下新建一个upload.jsp页面,新建文件上传表单

<h2>文件上传表单</h2>
<div>
  <form action="/upload" method="post" enctype="multipart/form-data">
    用户头像:<input type="file" name="headimg" />
    用户名:<input type="text" name="username" />
    <input type="submit">
  </form>
</div>
复制代码

文件上传表单一定要设置enctype属性且value为multipart/form-data,将请求体中的文件分段发送到服务器端

Spring MVC文件上传需要在Spring MVC配置文件上配置上传解析器CommonsMultpartResolver,否则无法解析文件上传请求,会出现http 400的报错

<!--配置文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="#{1024*1024*20}" />
    <property name="defaultEncoding" value="utf-8" />
</bean>
复制代码
  • defaultEncoding:必须和用户的JSP的pageEncoding属性一致,以便正确解析表单内容
  • maxUploadSize:设置文件上传的大小,可以根据上传文件适当设置

新增一个UploadController,用于处理文件上传

@Controller
public class UploadController {

    @RequestMapping("/upload")
    public String upload(@RequestParam(value = "username", required = false) String username,
                         @RequestParam("headimg")MultipartFile file,
                         Model model){
        System.out.println("上传文件表单中文件属性的名称:" + file.getName());
        System.out.println("上传文件请求中文件的名称:" + file.getOriginalFilename());
        System.out.println("上传文件请求中username的值为:" + username);

        // 上传文件
        try {
            file.transferTo(new File("/Users/jingnan/Practice/spring-mvc-ajax/" + file.getOriginalFilename()));
            model.addAttribute("msg", "文件上传成功");
        } catch (IOException e) {
            model.addAttribute("msg","文件上传失败" + e.getMessage());
        }

        return "forward:/upload.jsp";

    }
}
复制代码

使用Spring MVC进行上传文件非常方便,调用transferTo方法即可完成上传文件的操作

在upload.jsp文件中显示文件上传是否成功的提示

<h2>文件上传表单</h2>
${msg}
<div>
    <!--文件上传表单保持不变-->
</div>
复制代码

Restart the application, enter http://localhost:8080/upload.jsp in the browser, enter the file upload interface and enter the content of the file upload form

image.png

Click the submit button and the image.pngpage displays a message indicating that the file was uploaded successfully

image.pngAnd the console prints out the content of the file upload form and the form attribute information

Multiple file upload

Modify the upload file form

<h2>文件上传表单</h2>
${msg}
<div>
    <form action="/uploads" method="post" enctype="multipart/form-data">
        图片:<input type="file" name="headimg" /> <br>
        图片1:<input type="file" name="headimg" /> <br>
        图片2:<input type="file" name="headimg" /> <br>
        图片3:<input type="file" name="headimg" /> <br>
        图片4:<input type="file" name="headimg" /> <br>
        用户名:<input type="text" name="username" />
        <input type="submit">
    </form>
</div>
复制代码

A new method uploads is added in UploadController, which handles multiple file upload parameters to receive multiple files from the front end through the Mulpart array.

@RequestMapping("/uploads")
public String uploads(@RequestParam(value = "username", required = false) String username,
                     @RequestParam("headimg")MultipartFile[] files,
                     Model model){

    for (MultipartFile file : files) {
        System.out.println("上传文件表单中文件属性的名称:" + file.getName());
        System.out.println("上传文件请求中文件的名称:" + file.getOriginalFilename());
        // 保存文件
        try {
            file.transferTo(new File("/Users/jingnan/Practice/spring-mvc-ajax/" + file.getOriginalFilename()));
            model.addAttribute("msg", "文件上传成功");
        } catch (IOException e) {
            model.addAttribute("msg","文件上传失败" + e.getMessage());
        }
    }

    System.out.println("上传文件请求中username的值为:" + username);

    return "forward:/upload.jsp";
}
复制代码

Restart the application, and the browser opens the upload.jsp page

image.pngEnter the content in the form and click submit. The image.pngpage prompts that the file is uploaded successfully

image.pngThe information about the uploaded file is also printed in the back-end console

Guess you like

Origin juejin.im/post/7084964775301644301