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
All 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
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 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
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, 点击页面的超链接,即可获取所有员工的数据
@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, 点击提交按钮 请求提数据被打印在控制台中
在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 ,点击发送超链接
浏览器发送的请求体为JSON格式的数据
@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页面,点击发送按钮发送表单请求
控制台打印出消息体对象
@ResponseBody、ResponseEntity 与文件下载
该注解会将相应内容放在响应体中
@ResponseBody
@RequestMapping("/hello")
public String hello(){
return "success";
}
复制代码
访问/ha不会返回success页面,会直接返回字符串success
还可以自定义响应实体,这要求方法返回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 自定义的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 文件夹下
在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
Click the submit button and the page displays a message indicating that the file was uploaded successfully
And 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
Enter the content in the form and click submit. The page prompts that the file is uploaded successfully
The information about the uploaded file is also printed in the back-end console