SpringMVC的web.xml的配置文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5" >
<!--编码过滤器-->
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<!--请求乱码-->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<!--响应乱码-->
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!--配置处理请求方式为PUT和DELETE方式的请求:2个要求
1. 请求方式必选为POST请求
2. 请求参数必选传递 _method (放在隐藏域中)
-->
<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>
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!--加载springMCV的配置文件-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-mvc.xml</param-value>
</init-param>
<!--将前端控制器DispatcherServlet的启动时间提前到服务器启动时,不设置就是在第一次请求是启动DispatcherServlet-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<!--/ 表示拦截所有请求,除了.jsp /* 拦截所有请求,包含.jsp-->
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
Spring-MVC的配置文件
这两个要同时配置,然后发起一个请求的处理过程是:
- 先被DispatcherServlet处理,能处理就返回
- DispatcherServlet处理不了,找不到请求映射,就交给Tomcat的DefaultServlet处理处理不了的话,就404
<!--开发对静态资源的访问-->
<mvc:default-servlet-handler/>
<!--开启mvc注解驱动-->
<mvc:annotation-driven/>
当controller层中的方法不做任何处理,只转发视图时,就可以用view-controller配置代替
@RequestMapping("/hello")
public String hello() {
return "hello";
}
配置文件代替
<mvc:view-controller path="/hello" view-name="hello"/>
<mvc:view-controller path="/index" view-name="homepage"/>
注
WEB-INF下的资源具有安全性,不能通过浏览器(客户端)直接访问
也不能通过重定向访问
只能服务器内部转发
就算将页面放在webapp下,也不能进行访问。
因为页面中存在thymeleaf的语法,需要被thymeleaf的引擎解析,
就需要经过SpringMVC配置的视图解析器进行解析。
注:转发不能跨域,因为是服务器内部转发资源;重定向可以跨域,因为是两次请求。
@RequestMapping("/hello")
public String hello() {
//服务器内部经过视图解析器转发到webapp下的hello页面
return "hello";
}
跨域:浏览器的同源策略,协议,IP,端口
session是服务器的会话技术,而cookie是客户端的会话技术
session依赖于cookie
每当我们创建session时(例如,request.getSession()),就会去创建一个Map集合,key为JSESSONID的cookie,value为当前获取的session对象,存储在服务器内部。
Get请求的乱码是Tomcat造成的,只需要在Tomcat的配置文件server.xml中,找到端口开头配置文件的里面添加URIEncoding=UTF-8
<Connector port="8080" protocol="HTTP/1.1" URIEncoding=UTF-8
connectionTimeout="20000" redirectPort="8443" />
而request.setCharacterEncoding("UTF-8");
是用来解决POST请求乱码问题
且必须在获取请求参数执行设置编码,否则还是会有乱码。
Web服务器三大组件:监听器、过滤器、servlet
加载顺序:ServletContextListener > filter > servlet
ServletContextListener监听器:监听ServletContext的创建和销毁,只执行一次。
自定义监听器,就去实现ServletContextListener
(监听器,可以理解为事件,当触发这个事件后,就执行对应的操作)
public class MyInitListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
Filter:是作用在浏览器和Servlet之间的组件
在SpringMVC中,Filter就是作用在浏览器和DispatcherServlet之间的组件。
SpringMVC中的拦截器,是拦截中央控制器DispatcherServlet映射到的Controller中的请求方法。
即,作用于控制器执行的前后的。
自定义拦截器,去实现HandlerInterceptor
public class MyIntercept implements HandlerInterceptor {
//在请求方法之前执行
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
// true 就是放行,false 不放行
return false;
}
//在请求方法之后执行
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
//在渲染视图之后执行
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
三大域对象:request、session、ServletContext
request:一次请求
session:一次会话,即浏览器开启到浏览器关闭。与服务器是否关闭无关系,因为session中有钝化和活化。
当服务器关闭后,还存活的session将序列化的对象以文件的形式存储在tomcat的work目录,这就是钝化。
当服务器再次开启时,服务器会找到之前钝化的文件,从而恢复之前保存起来的Session对象,这就是活化。
所有session中的数据只跟浏览器是否关闭有关系。
ServletContext:整个应用的范围,即服务器开启到服务器关闭。只创建一次。
自定义响应报文(ResponseEntity),下载文件
@RequestMapping("/download")
//ResponseEntity 就是自定义响应报文去响应浏览器
public ResponseEntity<byte[]> hello(HttpServletRequest request) throws IOException {
ServletContext servletContext = request.getSession().getServletContext();
//获取文件的真实路径
String realPath = servletContext.getRealPath("/images/1.jpg");
//System.out.println(realPath);
InputStream is = new FileInputStream(realPath);
// is.available() 是来获取输入流的文件所对应的所有字节的,就是下载文件的字节数
byte[] bytes = new byte[is.available()];
is.read(bytes);
MultiValueMap<String, String> headMap = new HttpHeaders();
//设置以附件形式下载文件
headMap.add("Content-Disposition", "attachment;filename=1.jpg");
ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(bytes, headMap, HttpStatus.OK);
is.close();
return responseEntity;
}
注解代替web.xml配置文件
- 去继承
AbstractAnnotationConfigDispatcherServletInitializer
- 重写其中的方法
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
//必须满足servlet3.0的容器,才能去集成AbstractAnnotationConfigDispatcherServletInitializer类
//从而代替web.xml配置文件,即创建初始化类,代替web.xml文件
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
//获取根配置,即指定Spring配置类
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
//指定SpringMVC的配置类
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebConfig.class};
}
//指定DispatcherServlet的映射规则,即web.xml中,DispatcherServlet的url-pattern
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
/**
* 注册过滤器
* @return
*/
@Override
protected Filter[] getServletFilters() {
//编码过滤器
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
//处理请求方式为PUT和DELETE方式的请求 过滤器
HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
return new Filter[]{characterEncodingFilter, hiddenHttpMethodFilter};
}
}
注解代替SpringMVC的配置文件
//代替SpringMVC的配置文件
/*
1. 组件扫描 2. 视图解析器 3. view-controller
4. <!--开启对静态资源的访问-->
<mvc:default-servlet-handler/>
5. mvc注解驱动
6. 上传解析器
*/
@ComponentScan(basePackages = {"com.demo.*"})
//开启MVC注解驱动
@EnableWebMvc
@Configuration
public class WebConfig implements WebMvcConfigurer {
// 注册视图解析器
@Bean
public ViewResolver getViewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/pages/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
/**
* 4. 开启对静态资源的访问
* <mvc:default-servlet-handler/>
* @param defaultServletHandlerConfigurer
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer defaultServletHandlerConfigurer) {
defaultServletHandlerConfigurer.enable();
}
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry interceptorRegistry) {
MyIntercept myIntercept = new MyIntercept();
interceptorRegistry.addInterceptor(myIntercept)
//添加拦截路径
.addPathPatterns("/**")
//排除拦截路径
.excludePathPatterns("/hello");
}
//3. view-controller
@Override
public void addViewControllers(ViewControllerRegistry viewControllerRegistry) {
viewControllerRegistry
//设置映射路径
.addViewController("/index")
//设置视图名称
.setViewName("index");
}
//注册文件上传解析器
@Bean
public MultipartResolver getMultipartResolver() {
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setDefaultEncoding("UTF-8");
multipartResolver.setMaxUploadSize(200000000000L);
return multipartResolver;
}
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> list) {
}
@Override
public void addFormatters(FormatterRegistry formatterRegistry) {
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> list) {
}
@Override
public Validator getValidator() {
return null;
}
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer contentNegotiationConfigurer) {
}
@Override
public void configureAsyncSupport(AsyncSupportConfigurer asyncSupportConfigurer) {
}
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> list) {
}
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> list) {
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
return null;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry resourceHandlerRegistry) {
}
}
注意
@Bean中方法的参数,需要满足自动配置方式,才能作为方法的形参
即,IOC容器中,需要有这个组件,才能作为@Bean中方法的形参
IOC容器中有ProductDao这个组件,就可以自动装配,从而作为@Bean中方法的形参
DispatcherServlet中的HandlerExecutionChain
执行链包含三部分
(HandlerExecutionChain在处理请求之前创建的)
- 匹配到的控制器方法(handler,即我们自定义的控制器方法)
- 拦截器集合(包含SpringMVC自己的一个拦截器和我们自定义的拦截器)
- 拦截器索引(就是拦截器执行顺序的索引)
restful:
- get 查询
- post 新增
- put 修改
- delete 删除