springMVC(二)——处理返回值、常用注解、文件上传下载、异常处理、过滤器、拦截器
springMVC目录(下)
零、注意
一、maven web项目中,不能直接访问静态资源(html、css、js等)。
1、为什么不能直接访问静态资源?
因为拦截的是/
和/*.jsp
所以路径为/*.html
也会被拦截,但是dispatcherServlet不能处理这些html,需要交给tomcat默认的servlet去处理。
2、如何交给tomcat默认的servlet处理?
✳①交给默认servlet<mvc:defalut-servlet-handler></mvc:defalut-servlet-handler>
略②指定静态资源路径<mvc:resources mapping="映射路径(浏览器地址)" location="具体路径(webapp下的哪个文件夹下面的哪个静态资源)"></mvc:resources>
(没添加一个静态资源都需要指定,复杂了)
二、返回数据类型(response)
1、重定向返回数据,需要加RedirectAttributes属性,获取时需要使用@RedirectAttributes注解
2、返回任意类型的数据,需要加@ResponseBody返回值转为json格式;
自定义类,还需要开启自定义转换,才能生效,????<mvc:annotation-driven></mvc:annotation-driven>
三、拦截器与过滤器?
过滤器:tomcat提供的;
拦截器:springMVC提供的;用于对处理器进行预处理和后处理
四、Controller请求转发,json自动转换等功能
需要在spring的xml文件中添加<mvc:annotation-driven></mvc:annotation-driven>
主要就是为了Spring MVC来用的,提供Controller请求转发,json自动转换等功能
五、文件上传下载需要导入jar包、实例化文件上传下载工具
Ⅰ、springMVC返回值的处理
【待补充】
Ⅱ、springMVC常用注解 0
一、@RequestParam
位置:用在方法的入参位置
作用:用于前端传入的参数与方法形参匹配(前端传入的参数名与方法形参名不一致才使用,否则没必要)
属性:
1)value:默认属性,用于指定前端传入的参数名称;
2)required:用于指定此参数是否必传(boolean),默认为true,此时前端不传数据就会报错;
3)defaultValue:当参数为必传参数且前端没有传入参数时,必须指定一个默认值。
@RequestMapping("test1")
public String test1(@RequestParam(value = "user",required = true,defaultValue = "abc")String username){
System.out.println(username);
return "/index.jsp";
}
解释——前端前端将user=***,传到控制层,控制层使用username接收;因为required = true,此时如果前端没有将参数传过来,使用默认值,则username=abc
二、@RequestHeader
位置:用在方法入参位置
作用:用于从请求头中获取参数
属性:同@RequestParam
@RequestMapping("test2")
public String test2(@RequestHeader("cookie") String cookie){
System.out.println(cookie);//JSESSIONID=2D7************
return "/index.jsp";
}
请求头——
三、@CookieValue
位置:用在方法入参位置
作用:用于从cookie中获取参数
@RequestMapping("test3")
public String test3(@CookieValue("JSESSIONID") String jsessionid){
System.out.println(jsessionid);//2D7F453*********
return "/index.jsp";
}
四、@SessionAttributes(value={"…","…","…",……})
位置:放在类上
作用:将请求域的参数,放到session域中
AnnotationController.java
package com.hbw.controller;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
@Controller
@RequestMapping("annotation")
@SessionAttributes(value = {"a","b","c","d","e"})
public class AnnotationController {
@RequestMapping("test4")
public ModelAndView test4(Map map, Model model, ModelAndView modelAndView, ModelMap modelMap, HttpServletRequest request){
map.put("a","1");
model.addAttribute("b","2");
modelAndView.setViewName("/index.jsp");
modelMap.addAttribute("d","4");
request.setAttribute("e","5");
return modelAndView;
}
}
因为使用了request——tomcat内置对象之一,需要导入servlet-api的jar包
但是,新导入的jar包会与启动tomcat插件冲突,给jar包加个作用范围(scope=provided)
pom.xml
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
index.jsp
Map:${requestScope.get("a")}<br/>
Model:${requestScope.get("b")}<br/>
ModelMap:${requestScope.get("d")}<br/>
request:${requestScope.get("e")}
✳五、RequestBody
位置:用在方法入参位置
作用:用于接收前端传入的消息体,可将json格式转为对象格式。注意:只有post请求才有消息体。
注意:需要在spring的xml文件中添加<mvc:annotation-driven></mvc:annotation-driven>
主要就是为了Spring MVC来用的,提供Controller请求转发,json自动转换等功能
1)前端
<script>
$(function($) {
$.ajax({
type: "POST",
url: "/annotation/test5",
contentType:"application/json",
data: '{"bid":"123","bname":"语文"}',
success: function(msg){
alert( "Data Saved: " + msg );
}
});
});
</script>
2)后端
@RequestMapping("test5")
public String test5(@RequestBody Book book){
System.out.println(book);
return "/index.jsp";
}
3)控制台
Book{bid=123, bname=‘语文’}
✳六、ResopnseBody
位置:方法上
作用:将我们的返回值异步响应为json数据
????引用——
详细来说,就是将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据。
注意
在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。在使用 @RequestMapping后,返回值通常解析为跳转路径,但是加上 @ResponseBody 后返回结果不会被解析为跳转路径,而是直接写入 HTTP response body 中。 比如异步获取 json 数据,加上 @ResponseBody 后,会直接返回 json 数据。@RequestBody 将 HTTP 请求正文插入方法中,使用适合的 HttpMessageConverter 将请求体写入某个对象。
1)前端调用
<body>
<a href="/annotation/test6" >点击</a>
</body>
2)后端
@RequestMapping("test6")
@ResponseBody
public Book test6(){
Book book = new Book();
book.setBid(1);
book.setBname("数学");
return book;
}
3)响应给页面
页面显示——
{"bid":1,"bname":"数学"}
七、@ModelAttribute
作用:向请求域对象(request)中添加信息
位置:
1、放在方法入参位置上
1)从表单中获取普通的数据,同时将这个数据以表单控件的名称为key放入请求域中;
2)表单的数据被封装成一个自己定义的实体类对象,注解中的key可以任意取名。??????这点还没遇见,后面在补充吧
3)肯定也能获取下面这类方法中的返回参数
2、放在方法上
1)为当前的controller中所有可以直接访问的方法提供公共数据
1)前端
比如输入,Tom
<body>
<%--测试ModelAttribute--%>
<form action="/annotation/test7" method="post">
用户名:<input type="text" name="user">
<input type="submit">
</form>
</body>
2)后端
@RequestMapping("test7")
public String test71(@ModelAttribute("user")String user,@ModelAttribute("ceshi")String aa){
//获取表单提交过来的普通参数
System.out.println(user);
//获取公共方法提供的公共参数
System.out.println(aa);
return "/index.jsp";
}
@ModelAttribute("ceshi")
public String test72(){
System.out.println("我是公共方法,为其他共有方法提供参数");
return "公共参数";
}
3)控制台
我是公共方法,为其他共有方法提供参数
Tom
公共参数
八、@RequestMapping
位置:类上、方法上
作用:设置访问控制层的路径
method属性的第一个值表示只处理get请求;第二个值表示RESTFUL风格(见下一个标签)
@RequestMapping(value = "test8",method = {RequestMethod.GET,RequestMethod.PUT})
九、@PathVariable
位置:用在方法入参位置
作用:获取请求路径变量,通常用于restful风格编码。????
1、为什么要使用RESTful风格?
因为http协议中的url本身不具有表示状态的功能,是一个无状态请求协议。
2、那么如何表示操作状态呢?
我们通过请求方式指定状态:
新增:POST
删除:DELETE
修改:PUT
查询:GET
3、具体什么意思?以修改某个学生的信息举例
1)以往的风格:/updateStudentById?id=1
2)使用RESTful风格:/student/1
代码如下:
增加、查询没啥特别的;修改和删除需要加<input type="hidden" name="_method" value="PUT或者DELETE"/>
因为form的method属性默认值只有get、post。这里使用修改进行说明。
1)前端
<body>
<%--这里只是测试说明,直接指定修改的具体学生了--%>
<form action="/annotation/student/1" method="post">
<%--这里的name属性值,不要随便写,不然找不到--%>
<input type="hidden" name="_method" value="PUT"/>
<input type="submit"/>
</form>
</body>
2)后端
@RequestMapping(value = "student/{sid}",method = RequestMethod.PUT)
public String updatePerson1(@PathVariable("sid")String sid){
System.out.println("修改"+sid+"号学生");
return "/index.jsp";
}
3)web.xml中的配置
<!--用于对RESTful风格的拦截器 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4)结果
http://localhost:8080/annotation/student/1
Ⅲ、springMVC文件上传与下载
准备工作
1、引入jar包
<!--文件上传-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
2、初始化上传工具multipartResolver
就是文件上传解析器,它会将上传的文件进行封装
注意:id是固定的
<!--初始化文件上传、下载实例-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- <property name="maxUploadSize" value="102400000"></property>-->
</bean>
一、文件上传
1)、提交上传申请
<form action="/annotation/test9" method="post" enctype="multipart/form-data">
<%--name随便取,但是必须与处理请求的参数名相同。不然需要在入参位置使用@RequestParam("name属性的值")注解--%>
<input name="multipartFile" type="file">
<input type="submit" value="文件上传">
</form>
2)、处理上传请求
/*文件上传*/
@RequestMapping("test9")
public String test9(MultipartFile multipartFile){
//获取上传文件的名字,并在前面加上32位随机字符
String fileName =UUID.randomUUID() + multipartFile.getOriginalFilename();
//指定上传路径(客户端上传到服务器,不可能没有这个文件夹,让用户去创建。肯定是事先就准备有的文件夹)
File file = new File("H:\\FileLoad\\" + fileName);
try {
//上传,ovwe
multipartFile.transferTo(file);
} catch (IOException e) {
e.printStackTrace();
}
return "/index.jsp";
}
二、批量上传
1)前端请求
<form action="/annotation/test10" method="post" enctype="multipart/form-data">
<%--两个name必须一样,才是数组啊--%>
<input name="files" type="file">
<input name="files" type="file">
<input type="submit" value="文件批量上传">
</form>
2)后台处理
/*批量上传*/
@RequestMapping("test10")
public String test10(MultipartFile[] files){
for(MultipartFile file:files){
File newFile = new File("H:\\FileLoad\\" + UUID.randomUUID()+file.getOriginalFilename());
try {
file.transferTo(newFile);
} catch (IOException e) {
e.printStackTrace();
}
}
return "/index.jsp";
}
三、文件下载
1)前端请求
filePath表示该资源在服务器上的详细路径、filename表示待下载的文件的全名称
<a href="/annotation/test11?filePath=H:\\FileLoad\\123.png&filename=123.png">123.png下载</a>
2)后台处理
/*文件下载*/
@RequestMapping("test11")
//注意参数名与前端的参数名相同。不然需要使用@RequestParam(这是spring MVC获取前端传入数据自动匹配的规则)
public ResponseEntity<byte[]> test11(String filePath,@RequestParam("filename") String fileName) throws IOException {
File file = new File(filePath);
//定义响应头
HttpHeaders httpHeaders = new HttpHeaders();
//指定以下载的方式打开文件
httpHeaders.setContentDispositionFormData("attachment",fileName);
//指定下载文件的数据类型
return new ResponseEntity<byte[]>(FileUtils.readFileToByteArray(file),httpHeaders, HttpStatus.OK);
}
Ⅳ、springMVC异常处理
出现异常是非常正常的,但是应当根据实际需求创建合适的异常处理(客户端访问时,代码错误,不能给用户报500错误啊~应该跳转到错误页面等)不需要用户重复异常处理操作,减少代码的赘余,提高了程序的扩展性、维护性。
Ⅴ、springMVC过滤器
Ⅵ、springMVC拦截器
本文地址:https://blog.csdn.net/Today_He/article/details/109525397