springmvc
1,web.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<!--配置DispatcherServlet-->
<servlet-name>springMvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--指定spring mvc配置文件位置-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<!--设置启动顺序-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<!--匹配请求-->
<servlet-name>springMvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 配置过滤器解决前端发送数据到后端乱码问题-->
<filter>
<filter-name>character</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>character</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<!-- ***************************************************************-->
</web-app>
2,spring-mvc.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 注解扫描包-->
<context:component-scan base-package="com.zsa.controller"/>
<!-- 静态资源过滤-->
<mvc:default-servlet-handler/>
<!-- 开启注解同时配置处理器映射器和处理器解析器-->
<mvc:annotation-driven/>
<!-- 处理器映射器-->
<!-- <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->
<!-- 处理器适配器-->
<!-- <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>-->
<!-- 视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- <bean id="/hello" class="com.zsa.controller.Controller01"/>-->
<!-- 设置类型转换器的参数,解决中文乱码问题 -->
<mvc:annotation-driven >
<!-- 消息转换器 -->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- ********************************************************-->
</beans>
3,springmvc导入依赖
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>5.2.10.RELEASE</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>5.2.10.RELEASE</version> </dependency> <!-- jison数据转化,将后端对象转化为jison数据--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.9.0</version> </dependency> </dependencies>
4,controller的一些说明
1,如果在控制器类只添加@controller注解则表示所有接口的返回数据都会经过视图解析器跳转到spring-mvc.xml中拼接的指定页面
2,如果想要将数据返回到前端需要在接口上添加@respondboy此时数据会被前端接受如果返回的数据是一个字符串则需要添加
<mvc:annotation-driven >
<!-- 消息转换器 -->
<mvc:message-converters register-defaults="true">
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes" value="text/html;charset=UTF-8"/>
</bean>
</mvc:message-converters>
</mvc:annotation-driven
来解决返回乱码问题
3,返回到前端的数据如果是一个对象或者集合则需要导入 ackson-databind依赖此时对象或者集合会被自动转换为jison数据
5,对restful的一些说明
1,restful风格数据形参不会被显示的写在前端的url地址中,后端在接受数据时才指定形参的名称
并且要在方法的形参中加入@PathVariable注解表从url中获取形参的值
@GetMapping("/{id}")
public Result getById(@PathVariable int id){
Book book = bookService.getById(id);
int flag=book!=null?Code.get_ok:Code.get_err;
String msg =book!=null?null:"查询失败";
return new Result(flag,msg,book);
}
2, restful风格把请求大致分为以下四大类
@GetMapping | 对应前端的get请求通常用于查询数据 |
@PostMapping | 对应前端的post请求用于将前端传来的数据进行保存操作 |
@DeleteMapping | 对应前端的delete请求用于删除操作 |
@PutMapping | 对应前端的post请求用于将前端传来的数据进行更新操作 |
6,接口返回数据的一些说明
1,在开发中我们通常会将接口返回的封装到一个Result对象中
public class Result { private int code;//码值 private String msg;//错误信息 private Object date;//返回值对象 }在date中我们通常放入查询到的对象或者集合
我们通过对构造器的重载用来满足delete和post,update这些操作不返回date的操作
code的值为我们定义好的Code类里面的常量
7,重定向和转发
在springmvc中通过重定向和转发无需经过视图解析器
转发:没有配置视图解析器的情况:在return后返回的字符串为"forward:/页面的全路径名"
配置了视图解析器:return为视图名称
重定向:在return后返回的字符串为"redirect:/页面的全路径名"
重定向和转发的区别:转发的页面可以是WEB-INF下的页面 但是重定向不可以是WEB-INF下的页面
重定向相当于用户重新发出一次请求
在转发和重定向中不能使用@ResponseBody注解 这个注解将响应的数据直接写到response中body里,跳过视图解析器,直接写到响应流里,此时我们的重定向和转发就失效了
8,异常处理
在ssm的整合中我们会将发生的异常统一交由controller层进行处理在controll层我们会创建一个异常处理类对异进行分类处理
异常处理的步骤
1,在spring-mvc.xml中开启注解
xmlns:mvc="http://www.springframework.org/schema/mvc"
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
2,注解扫描范围为controller下的全部包
3,在自定义注解类上添加@RestControllerAdvice
4,用@ExceptionHandle来对分类处理
@RestControllerAdvice public class ExceptionHandle { @ExceptionHandler(Exception.class) public Result getException(){ return new Result(666,"666出bug了",null); } }在这里我仍将异常信息封装到Result的返回到前端中
9,拦截器
1,拦截器的配置
1,在spring-web.xm中配置拦截器
<mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/**"/> <bean class="com.zsa.controller.MyInterceptor"/> </mvc:interceptor> </mvc:interceptors>
2,在controller层添加一个拦截器类实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor {
//此方法返回为true时才会继续执行postHandle,afterCompletion方法
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("1");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("2");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("3");
}
}
2,常见应用场景
(1)、日志记录:记录请求信息的日志,以便进行信息监控、信息统计、计算PV(Page View)等。
(2)、权限检查:如登录检测,进入处理器检测检测是否登录,如果没有直接返回到登录页面;
(3)、性能监控:有时候系统在某段时间莫名其妙的慢,可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间(如果有反向代理,如apache可以自动记录);
(4)、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
(5)、OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。
本质也是AOP(面向切面编程),也就是说符合横切关注点的所有功能都可以放入拦截器实现
原文链接:https://blog.csdn.net/xhaimail/article/details/79739264
3,拦截器的执行时机
preHandle():这个方法在业务处理器处理请求之前被调用,在该方法中对用户请求request进行处理,如果该拦截器请求进行拦截处理后还要调用其他的拦截器,或者是业务处理器去进行处理,则返回true,否则返回false
postHandle():这个方法在业务处理器处理完请求后,但是DispatcherServlet向客户端返回响应前被调用,在该方法中对用户请求request进行处理
afterCompletion():这个方法在DispatcherServlet完全处理完请求后被调用,可以在该方法中进行一些资源清理的操作,无论是否产生异常都会在渲染视图后执行的方法
原文链接:https://blog.csdn.net/weixin_43912883/article/details/102585588
10,文件的上传和下载
文件上传
导入依赖
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> </dependency>
spring-mvc.xml文件配置
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 最大允许上传大小5MB --> <property name="maxUploadSize" value="5242880" /> <property name="maxInMemorySize" value="4096" /> <property name="defaultEncoding" value="UTF-8"></property> </bean>id="multipartResolver"不可以改动
form表单的需要加入 enctype="multipart/form-data"用于文件提交
@RequestMapping("/testUp")
//SpringMVC中将上传的文件封装到MultipartFile对象中,通过此对象可以获取文件相关信息
public String testUp(MultipartFile photo, HttpSession session) throws IOException {
//获取上传的文件的文件名
String fileName = photo.getOriginalFilename();
//处理文件重名问题
String hzName = fileName.substring(fileName.lastIndexOf("."));
fileName = UUID.randomUUID().toString() + hzName;
//获取服务器中photo目录的路径
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
if(!file.exists()){
file.mkdir();
}
//在Java中,文件分隔符是系统相关的,在Windows系统中是“\”,在Linux系统中是“/”。在上述代中,
//File.separator用于获取系统的文件分隔符。
String finalPath = photoPath + File.separator + fileName;
//实现上传功能
photo.transferTo(new File(finalPath));
return "success";
}
文件下载
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testResponseEntity(HttpSession session) throws IOException {
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/1.jpg");
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeaders对象设置响应头信息
MultiValueMap<String, String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition", "attachment;filename=1.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象 ResponseEntity用于设置控制器方法的返回值类型
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes, headers, statusCode);
//关闭输入流
is.close();
return responseEntity;
}