24.12.27 SpringMVCDay02
[*]
[*]enctype必须是 multipart/form-data
<form action="/mvc/book/doUpload1" method="post" enctype="multipart/form-data">
<p>
<input type="file" name="img_url">
</p>
<p>
<input type="submit" value="上传">
</p>
</form>
@Autowired
HttpServletRequest request;
@PostMapping("/doUpload1")
@ResponseBody
public String doUpload1() throws ServletException, IOException {
//获取Request对象
//getPart(页面表单提交中,获取name=img_url的值
Part part = request.getPart("img_url");
//文件存哪里
//D:\webFolder\mvcdemo1\target\mvcdemo\
String realPath = request.getServletContext().getRealPath("/");
//D:\webFolder\mvcdemo1\target\mvcdemo\/imgs/
String basePath = realPath + "/imgs/";
System.out.println(basePath);
//文件夹是否存在
File baseFile = new File(basePath);
if (!baseFile.exists()){
baseFile.mkdirs();
}
//文件名
String fileName = part.getSubmittedFileName();
part.write(basePath + fileName);
return "success";
} 多文件
multiple属性
<form action="/mvc/book/doUpload2" method="post" enctype="multipart/form-data">
<p>
<input type="file" name="img_url" multiple>
</p>
<p>
<input type="submit" value="上传">
</p>
</form>
@PostMapping("/doUpload2")
@ResponseBody
public String doUpload2() throws ServletException, IOException {
//获取 所有的文件
Collection<Part> parts = request.getParts();
String realPath = request.getServletContext().getRealPath("/imgs/");
System.out.println(realPath);
File realFile = new File(realPath);
if (!realFile.exists()){
realFile.mkdirs();
}
parts.forEach(part -> {
String fileName = part.getSubmittedFileName();
try {
part.write(realPath +fileName);
} catch (IOException e) {
//不处理异常,仅仅是打印看看
e.printStackTrace();
}
});
return "success";
} MVC方式上传文件
[*]引入依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
</dependency>
[*]mvc.xml
<!--上传文件的配置-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/>
</bean>
单文件
//img_url表单提交中的name属性
@PostMapping("/doUpload3")
@ResponseBody
public String doUpload3(MultipartFile img_url) throws IOException {
//文件名
String fileName = img_url.getOriginalFilename();
//获取保存路径
String realPath = request.getServletContext().getRealPath("/imgs/");
System.out.println(realPath);
File realFile = new File(realPath);
if (!realFile.exists()){
realFile.mkdirs();
}
//文件对象.transferTo(存储的位置+文件名)
img_url.transferTo(new File(realPath + fileName));
return "success";
} 多文件
@PostMapping("/doUpload4")
@ResponseBody
public String doUpload4(MultipartFile[] img_url) throws IOException {
if (img_url.length > 0){
for (MultipartFile file : img_url){
file.transferTo(new File(getFileName(file)));
}
}
return "success";
}
private String getFileName(MultipartFile file){
//文件名
String fileName = file.getOriginalFilename();
//获取保存路径
String realPath = request.getServletContext().getRealPath("/imgs/");
File realFile = new File(realPath);
if (!realFile.exists()){
realFile.mkdirs();
}
return realPath + fileName;
} 文件下载
默认情况下,mvc框架,无法辨认静态资源文件的
超链接下载
<ul>
<li>
<a href="/mvc/save/test1.docx">word文档</a>
</li>
<li>
<a href="/mvc/save/test2.jpg">图片</a>
</li>
<li>
<a href="/mvc/save/test3.pdf">PDF</a>
</li>
<li>
<a href="/mvc/save/test4.rar">压缩文件</a>
</li>
<li>
<a href="/mvc/save/test5.xlsx">Excel</a>
</li>
</ul>
假如这个文件,欣赏支持,可以打开,就会直接在欣赏器中打开,不进行下载
假如这个文件,欣赏器无法打开,跳出下载页面
利益:简单,易学.写一个url地址超链接即可
弊端:仅能让部分格式的文件下载
流下载
这个下载 ,要经过服务器,让服务器写出文件流 给欣赏器,触发下载
[*]ResponseEntity
@Autowired
HttpServletRequest request;
@GetMapping("/test1")
public ResponseEntity<byte[]> download(String name) throws IOException {
//获取文件路径
String realPath = request.getServletContext().getRealPath("/save/");
//文件的全路径
String allPath = realPath + name;
//获取下载需要的文件流信息
FileInputStream inputStream = new FileInputStream(allPath);
//获取流的数组
byte[] buffer = new byte;
//读取
inputStream.read(buffer);
//文件下载的时候,显示的名字,需要改文件名了,再修改
//设置响应的头信息,告诉浏览器,返回的是文件
HttpHeaders httpHeaders = new HttpHeaders();
//设置响应的头信息,访问文件名中文乱码
httpHeaders.setContentDispositionFormData("attachment", URLEncoder.encode(name,"utf-8"));
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(buffer,httpHeaders, HttpStatus.OK);
return responseEntity;
}
[*]HttpServletResponse
@Autowired
HttpServletResponse response;
@GetMapping("/test2")
public voiddownload2(String name) throws FileNotFoundException, UnsupportedEncodingException {
//获取文件路径
String realPath = request.getServletContext().getRealPath("/save/");
//文件的全路径
String allPath = realPath + name;
//判断文件是否存在
File file = new File(allPath);
if (!file.exists()){
throw new FileNotFoundException(name+"文件不存在");
}
//代码能执行到这一行,说明文件肯定存在
//编码格式是utf-8的文件名
String encodeFileName = URLEncoder.encode(name, StandardCharsets.UTF_8.toString());
//设置头信息 header
response.setHeader("Content-Disposition","attachment;filename*=UTF-8''"+encodeFileName);
//使用 try--with --resources 关闭流
try(FileInputStream inputStream = new FileInputStream(file);
OutputStream outputStream = response.getOutputStream()){
IOUtils.copy(inputStream,outputStream);
outputStream.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
} 异常处置惩罚
[*]异常页面
[*]
[*]修改web.xml (会直接跳到这个页面)
<error-page>
<location>/error.jsp</location>
</error-page>
[*]异常类
@Component
public class TestController implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request,
HttpServletResponse response,
Object o,
Exception e) {
//产生异常的时候,调用这个方法
System.out.println(e.getMessage());
e.printStackTrace();
//配置返回值
ModelAndView mv = new ModelAndView();
mv.setViewName("game/success");//会直接跳到 webapp下的这个页面
return mv;
}
}
[*]@RestControllerAdvice
用来处置惩罚指定异常(自定义异常类)
@RestControllerAdvice
public class JavasmExceptionAdvice {
//当ArithmeticException被抛出来的时候,执行当前方法
@ExceptionHandler(ArithmeticException.class)
public String f1(ArithmeticException e){
System.out.println("算术异常");
e.printStackTrace();
//返回值,会代替原有方法的返回内容
return e.getMessage();
}
//当抛出JavasmException的时候,执行当前方法
@ExceptionHandler(JavasmException.class)
public Map<String,Object> f2(JavasmException e){
Map<String,Object> map = new HashMap<>();
map.put("code",500);
map.put("msg","自定义异常"+e.getMessage());
return map;
}
} public class JavasmException extends RuntimeException{
public JavasmException() {
}
public JavasmException(String message) {
super(message);
}
} 拦截器
拦截器 和 过滤器 的区别是什么?
过滤器:web容器,不属于框架,哀求进入tomcat之后,先经过的就是过滤器
拦截器:属于spring容器,springweb中,属于 容器的servlet,相当于,Servlet内部的哀求拦截
https://img-home.csdnimg.cn/images/20230724024159.png?origin_url=assets%2Fimage-20241227145848189.png&pos_id=O1tVGXLj
public class TestInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("pre--xxx之前----在Controller的方法 执行之前");
//返回的数据是Boolean类型,返回true,允许进入下一层(可能是下一个拦截器,也可能是Controller)
//返回false????
//response.getWriter().write("xxxx");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("post--xxx之后-----被访问的方法 执行结束之后,执行");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("页面渲染成功之后执行");
}
} 案例登录拦截
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//只有登录的用户才能访问系统
HttpSession session = request.getSession();
Object user = session.getAttribute("user");//登录的数据存在session,在这里取出
if (user != null){
//已经登录了
return true;
}
Map<String,Object> map = new HashMap<>();
map.put("code",2001);
map.put("msg","未登录");
String s = JSON.toJSONString(map);
response.setContentType("application/json;charset=utf-8");//预防乱码
PrintWriter writer = response.getWriter();
writer.write(s);
writer.flush();
writer.close();
return false;
}
} <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 开启包扫描--> <context:component-scan base-package="com.javasm"/> <!--代替适配器等配置--> <mvc:annotation-driven/> <!--视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--跳转的jsp页面,统一添加前缀--> <property name="prefix" value="/WEB-INF/"/> <!--后缀--> <property name="suffix" value=".jsp"/> </bean> <!--静态资源文件放过--> <mvc:default-servlet-handler/> <!--上传文件的配置-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/>
</bean>
<!--配置拦截器--> <mvc:interceptors> <mvc:interceptor> <!--被拦截的路径--> <!--所有以/game开头的哀求,都要经过拦截器--> <mvc:mapping path="/game/**"/> <mvc:mapping path="/player/**"/> <!--在包罗的路径中,排除其中的某些路径--> <mvc:exclude-mapping path="/game/test1"/> <!--拦截器类--> <bean class="com.javasm.interceptor.TestInterceptor"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> //拦截页面的范围 <mvc:exclude-mapping path="/game/test1"/> //不会被拦截的页面 <mvc:exclude-mapping path="/login/**"/> <bean class="com.javasm.interceptor.LoginInterceptor"/>//拦截所在的位置 </mvc:interceptor> </mvc:interceptors></beans> 数据范例转换
Field error in object 'bookModel' on field 'ctime': rejected value ; codes ; arguments ; arguments []; default message ]; default message to type for value '2024-12-27'; nested exception is java.lang.IllegalArgumentException]] 表单提交的是String范例数据,实行自动转成Date范例,失败了
@PostMapping("/doAdd2")
@ResponseBody
public Date doAdd2(String name,@DateTimeFormat(pattern = "yyyy-MM-dd") Date ctime){
return ctime;
} @PostMapping("/doAdd")
@ResponseBody
public BookModel doAdd(BookModel book){
return book;
}
@Data
public class BookModel {
private Integer id;
private String name;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date ctime;
} 自定义参数范例转换器
SimpleDate转换
public class StringToDate implements Converter<String, Date> {
@Override
public Date convert(String s) {
//传入的参数,等待被转换的2024-12-27 字符串
System.out.println(s);
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date = null;
try {
date = simpleDateFormat.parse(s);
} catch (ParseException e) {
throw new RuntimeException(e);
}
return date;
}
} <?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd"> <!-- 开启包扫描--> <context:component-scan base-package="com.javasm"/> <!--代替适配器等配置--> <mvc:annotation-driven conversion-service="conversionJavasmService"/> <!--视图解析器--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!--跳转的jsp页面,统一添加前缀--> <property name="prefix" value="/WEB-INF/"/> <!--后缀--> <property name="suffix" value=".jsp"/> </bean> <!--静态资源文件放过--> <mvc:default-servlet-handler/> <!--上传文件的配置-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"/>
</bean>
<!--配置拦截器--> <mvc:interceptors> <mvc:interceptor> <!--被拦截的路径--> <!--所有以/game开头的哀求,都要经过拦截器--> <mvc:mapping path="/game/**"/> <mvc:mapping path="/player/**"/> <!--在包罗的路径中,排除其中的某些路径--> <mvc:exclude-mapping path="/game/test1"/> <!--拦截器类--> <bean class="com.javasm.interceptor.TestInterceptor"/> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/**"/> <mvc:exclude-mapping path="/game/test1"/> <mvc:exclude-mapping path="/login/**"/> <bean class="com.javasm.interceptor.LoginInterceptor"/> </mvc:interceptor> </mvc:interceptors> <!--消息范例转换--> <bean id="conversionJavasmService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <property name="converters"> <set> <bean class="com.javasm.convert.StringToDate"/> </set> </property> </bean></beans> localdateTime
Field error in object 'bookModel' on field 'utime': rejected value ; codes ; arguments ; arguments []; default message ]; default message to type for value '2024-12-27T16:08'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value ]] public class StringToDateTime implements Converter<String, LocalDateTime> {
@Override
public LocalDateTime convert(String s) {
return LocalDateTime.parse(s, DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
} <!--消息类型转换-->
<bean id="conversionJavasmService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.javasm.convert.StringToDate"/>
<bean class="com.javasm.convert.StringToDateTime"/>
</set>
</property>
</bean>
JSON数据(用JSON传输数据)
[*]引入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
<version>2.11.2</version>
</dependency>
[*]加注解
@GetMapping ("/doAdd3")
@ResponseBody
public BookModel doAdd3(@RequestBody BookModel book){
System.out.println(book);
return book;
} @Data
public class BookModel {
private Integer id;
private String name;
//@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date ctime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime utime;
} {
"id":1001,
"name":"<刑法>",
"ctime":"2024-12-27",
"utime":"2024-12-27 16:09:30"
}
json时间,可以写2024-01-27 09:09:09
不能写 2024-1-27 9:9:9
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]