SpringMVC详解

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的配置文件

这两个要同时配置,然后发起一个请求的处理过程是:

  1. 先被DispatcherServlet处理,能处理就返回
  2. 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配置文件
  1. 去继承AbstractAnnotationConfigDispatcherServletInitializer
  2. 重写其中的方法
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在处理请求之前创建的)

  1. 匹配到的控制器方法(handler,即我们自定义的控制器方法)
  2. 拦截器集合(包含SpringMVC自己的一个拦截器和我们自定义的拦截器)
  3. 拦截器索引(就是拦截器执行顺序的索引)

restful:

  1. get 查询
  2. post 新增
  3. put 修改
  4. delete 删除
  • 9
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值