SpringMVC

JavaWeb三大组件和环境特点

在这里插入图片描述

SpringMVC简介(M:mode V:view C:controller)

SpringMVC是一个基于Spring开发的MVC轻量级框架,SpringMVC和Spring可以无缝整合,使用DispatcherServlet最为前端控制器,其内部提供了处理器映射器、处理器适配器、视图解析器等组件,可以简化JavaBean封装,Json转化、文件上传等操作

加载applicationConext

核心流程:ServletContextListener–>获取ServletContext初始化参数(配置文件路径)–>创建ApplicationContext
如下:

public class ApplicationListener implements ServletContextListener {
    private final  String  CONTEXTCONFIGLOCATION="contextConfigLocation";
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        System.out.println("ServletContextListener");
        final ServletContext servletContext = servletContextEvent.getServletContext();
        final String contextLocation = servletContext.getInitParameter(CONTEXTCONFIGLOCATION);
        // 初始化加载 applicationContext
        final String substring = contextLocation.substring("classpath:".length());
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(substring);
        servletContext.setAttribute("applicationContext", applicationContext);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

框架配置-初始化加载applicationContext

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
    
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

SpringMVC:框架设计思想和思路

在这里插入图片描述

SpringMVC:请求的处理流程

  1. 用户发送请求至前端DispatcherServlet(核心)
  2. DispatcherServlet收到请求调用HandlerMapping映射处理器
  3. 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找),生成处理器对象及处理器拦截器(如有有则生成)一并返回给DispatcherServlet
  4. DispatcherServlet调用HandlerAdapte适配处理器
  5. HandlerAdapter经过适配器调用具体的处理器(Controller,也叫后端控制器)
  6. Controller执行完成返回ModeAndView
  7. HandlerAdapter将controller执行结果ModeAndView返回给DispatcherServlet
  8. DispatcherServler将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体的View
  10. DispatcherServlet根据View进行渲染视图(即将模型填充至视图中),DispatcherServlet响应用户
    在这里插入图片描述
    在这里插入图片描述

框架配置-前端控制器DispatcherServlet

 <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <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>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

源码

默认配置
在这里插入图片描述

核心:加载流程, 先去IOC容器查找组件,如果找不到则执行配置文件所配置的

在这里插入图片描述

SpringMVC请求处理

请求映射的处理

配置映射路径,映射器处理器才能找到Controller的方法资源,目前主流的配置方式是@RequestMapping
在这里插入图片描述
@RequestMapping(value=“/test”,method=RequestMethod.POST,params={“userName”,“age!=10”},headers={}):

  • value=url;
    支持通配符
    ant风格模糊路径
    ?:匹配任意一个字符
    * : 匹配任意的字符,以及一层路径
    **:代替多层路径
  • method:请求方式
  • params:请求参数控制
    • 1、设置必传参数
    • 2、设置参数校验
  • headers:请求头信息

请求数据的接收

1. 请求参数为key=value,请求的参数和处理方法的参数名一致接收
    // localhost/input?username=xusx&age=12
    public  String intputParam(String name,int age){

请求参数为key=value,请求的参数和处理方法的参数不一致
为解决参数名不一致异常:产生RequestParam来解决请求参数相关问题
@RequestParam(value=“name”,requird=false,defaultVlue=“a”) String username
- value:请求参数名
- requird: 是否必传
- defaultVlue: 默认值

 // localhost/input?username=xusx&age=12
    public  String intputParam(@RequestParam(value = "username",required = false,defaultValue = "111") String name,int age){}
  • 请求参数数组 key=value1&key=value2&key=value3 数组接收
    // localhost/inputArr?hobby=a&hobby=b&hobby=c
    - 方式1:  public String inputArr(String[] hobby){}
    - 方式2:  public String inputArr(@RequestParam List<String> hobby){} 
  • 请求参数为key=value,Map接收
    // localhost/inputMap?username=xusx&age=12
    public  String inputMap(@RequestParam Map<String,String> map){}

RequestParam则,指定无需封装对象直接放入即可

2. 请求参数与JavaBean属性一致,则经行自动封装为JavaBean
    // http://localhost:8099/inputObj?username=xusx&age=12&address.city=xj
	// http://localhost:8099/inputObj      {"username":"xusx","age":"12"}

    public String  inputObj(User user){}

	public class User {
	    private String username;
	    private String age;
	    private Address address;
	}
	public class Address {
	    private String city;
	}
3. @请求参数为字符串Requestbody将请求体参数封装到指定的参数

get方式无请求体

    @RequestMapping("/inpuBody")
    public String  inpuBody(@RequestBody String string){}
  • 当请求体中的数据为json字符串
    • 使用jackson可以经行Json字符换和JavaBean直接转换(单接口处理)
   ObjectMapper mapper = new ObjectMapper();
        final User user = mapper.readValue(string, User.class);
  • 配置RequestMappingHandleAdapter指定消息转换器统一处理Json字符串和JavaBean转换(全接口处理)
  <!--消息转换器-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
            </list>
        </property>
    </bean>

    /*
    {"username":"xusx","age":"1","address":{ "city":"tj"}}
     */
    @RequestMapping("/inpuJson")
    public String inpuJson(@RequestBody User user) throws IOException {}
4. @请求参数对对象集合
/*
[ {"username":"xusx","age":"1","address":{ "city":"tj"}, {"username":"zj","age":"12","address":{ "city":"bj"}]
*/
    @RequestMapping("/inputJsonArr")
    public String inputJsonArr(@RequestBody List<User> userList) throws IOException {}
文件上传
  • 表单提交方式为Post
  • 表单的enctype必须为multipart/form-data
    补充:multipart/form-data和x-www-form-urlencode区别
    默认状况下是 application/x-www-urlencoded,当表单使用 POST 请求时,数据会被以 x-www-urlencoded 方式编码到 Body 中来传送
    multipart/form-data 用以支持向服务器发送二进制数据

而若是 GET 请求,则是附在 url 连接后面来发送。

  • 文件上传项必须有name属性

    配置文件上传解析器
    单文件:MultipartFile file或不同名称的多个参数
    多文件:MultipartFile[] files 多个同名称参数

// id 必须屋为:multipartResolver,因为查找文件上传解析是根据id查找的
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="defaultEncoding" value="UTF-8"></property>    -- 编号格式
    <property name="maxInMemorySize" value="1048576"></property>  -- 
    <property name="maxUploadSizePerFile" value="1048576"></property>
    <property name="maxUploadSize" value="3145728"></property>  -- 最大上传大小
</bean>

<dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.4</version>
</dependency>

// MultipartFile 去指定接收类型
    @RequestMapping("/inputFile")
    public  String inputFile(@RequestBody MultipartFile myFile) throws IOException {
        System.out.println(myFile);
        final InputStream inputStream = myFile.getInputStream();
        OutputStream outputStream = new FileOutputStream("D:\\"+myFile.getOriginalFilename()+".txt");
        IOUtils.copy(inputStream, outputStream);
        inputStream.close();
        outputStream.close();
        return "index.jsp";
    }
请求头@RequestHeader
 @RequestMapping("/queryHead")
    public String queryHead(@RequestHeader("Connection") String connection) {}
cook获取@CookieValue
 @RequestMapping("/queryCook")
    public String queryCook(@CookieValue("JSESSIONID") String sessionId){
原生API
String getAPI(HttpServletRequest request)		
		httpservletrequest,
		httpservletresponse,
		httpsession,
		java.security.princioal,
		loacl,
		inputstream,
		outputstream,
		reader,
		writer.
获取Request域中属性@RequestAttribute

@RequestMapping(“/setResAttr”)
public String setResAttr(HttpServletRequest request){
request.setAttribute(“attr”,“撒哇哇阿斯顿”);
return “/getRstAttr”;
}

@RequestMapping("/getRstAttr")
public String getRstAttr(@RequestAttribute("attr") String attr){
    System.out.println(attr);
    return "index.jsp";
}

静态资源访问

JavaWeb原始开发时静态资源文件时可以直接被访问当
原因为: tomcat-config-web.xm提供了默认的servlet处理静态资源的访问
在这里插入图片描述

在这里插入图片描述
处理方式:

  1. 再次激活Tomcat下的defaultServlet去经行url-pattern匹配
    在这里插入图片描述
  2. Springmvc配置静态资源的映射
 <!--配置静态资源访问映射-->
    <mvc:resources mapping="/img/*" location="/img/"></mvc:resources>
  1. Springmvc配置注册DefaultServletHttpRequestHandle出处理(用的最多
<mvc:default-servlet-handler/>

2.3同理源码:根据命名空间去寻找
在这里插入图片描述
查找
在这里插入图片描述
注册SimpleUrlHandlerMapping
在这里插入图片描述
[SimpleUrlHandlerMapping优先加载注册在IOC容器中的则会造成]re(#centre)

annotation-driven注解

此注解会帮我们在内部注册RequestMappingHandlerMapping、RequestMappingHandlerAdapter并注入Json消息转换器
还提供以下支持:
1、支持使用ConversionService实例对表单参数进行类型转换
2、支持使用@NumberFomat annotion、@DataTimeFormat注解完成数据类型的格式化
3、支持使用 @Valid 注解对JavaBean实例进行JSR303验证
4、支持使用 @RequestBody 和@ResoponseBody注解

<mvc:annotation-driven/>

替换

   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"></bean>

    <!--Json消息转换器-->
    <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
        <property name="messageConverters">
            <list>
                <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"></bean>
            </list>
        </property>
    </bean>

SpringMVC响应处理

传统同步业务数据响应

  • 请求资源转发
  @RequestMapping("/forwardJsp")
    public String forwardJsp(){
        return "forward:index.jsp";
    }
  • 请求资源重定向
 @RequestMapping("/redirectJsp")
    public String redirectJsp(){
        return "redirect:index.jsp";
    }
  • 响应数据模型 ModelAndView
    将ModelAndView中添加的数据放入 request域中,path路径为视图解析器的路径。
   @RequestMapping("/modelandview")
    public ModelAndView modelandview(ModelAndView modelAndView){
        User user = new User();
        user.setUsername("xusx");
        modelAndView.addObject("user", user);
        modelAndView.setViewName("index.jsp");
        return modelAndView;
    }
  • 直接回写客户端 @ResponseBody注解
    告知SpringMVC框架,以响应体返回数据并非视图名

前后端分离异步数据响应

注:同步与异步数据响应的区别

  1. 同步方式回写数据,时将数据响应给浏览器经行页面展示的,而异步方式回写数据一般是回写给Ajax引擎的,即谁访问服务器端,服务器端就将数据响应给谁
  2. 同步方式回写的数据,一般就是一些无特定格式的字符串,而异步方式回写的数据大多都是JSON格式字符串
  • 直接回写客户端 @ResponseBody注解
    ResponseBody会调用配置的消息转换器,将对象转换为JSON字符串输出
    RestController=@Controller+@ResponseBody
 @RequestMapping("/jsonStr")
    @ResponseBody
    public User jsonStr() throws JsonProcessingException {
        User user=new User();
        user.setUsername("dasd");
        user.setAge("11");
        return user;
    }

SpringMVC的拦截器

拦截器Interceptor简介

SpringMVC的拦截器Interceptor规范,主要是对Controller资源访问时经行拦截操作的技术,当然拦截后可以经行授权控制,功能增强等;
Filter和Interceptor区别在这里插入图片描述
在这里插入图片描述
HandlerInterceptor接口方法的作用及其参数、返回值详解如下:

在这里插入图片描述

拦截器Interceptor配置

自定义类实现HandlerInterceptor接口,实现:preHandle、postHandle、afterCompletion
afterCompletion是否执行取决与preHandle返回true|false

<!--拦截器-->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/*"/>  <!-- 拦截路径 -->
            <bean class="com.yinhai.xusx.inteceptor.Myinteceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

拦截器执行顺序

其顺序是按照配置时的顺序执行的
在这里插入图片描述

当Interceptor1和Interceptor2处于放行,Inteceptore处于不放行时,执行如下
afterCompletion是否执行取决与preHandle返回true|false
在这里插入图片描述

全注解开发

spring-mvc.xml转化为注解

  • <mvc:annotation-driven/> <mvc:default-servlet-handler/> <mvc:interceptor>替换
    @EnableWebMvc
    源码
    在这里插入图片描述
    在这里插入图片描述
@Component
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();// 开始默认DefaultServlet
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new Myinteceptor()).addPathPatterns("/*");
    }
}

在这里插入图片描述

web.xml 转发为注解

待定吧

前端控制器DispatcherServlet

前端控制器初始化

主要两作用

  1. 初始化Spring和Springmvc容器
    Spring是Springmvc的父容器。获取Bean时,子可以查父(getParent),父无法查子
    在这里插入图片描述
  2. 初始化九大组件
    在这里插入图片描述

前端控制器主流程

在这里插入图片描述

SpringMVC异常处理机制

SpringMVC异常处理流程

一直往上抛,都抛给前端控制器DispatcherServlet,后由其调用异常处理器去处理
在这里插入图片描述

SpringMVC异常处理的方式

  1. 简单的异常处理器:使用SpringMVC内置的异常处理器处理SimpleMappingExceptionResolver
    主要作用:异常控制视图跳转
    <bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
        <!-- 默认异常跳转-->
        <property name="defaultErrorView" value="error.jsp"></property>
        <!--具体异常的处理-->
        <property name="exceptionMappings">
            <props>
                <prop key="java.lang.NullPointerException">null.jsp</prop>
                <prop key="java.io.FileNotFoundException">fileNot.jsp</prop>
            </props>
        </property>
    </bean>
  1. 自定义异常处理器:实现HandlerExceptionRexolver接口,自定义异常处理
    主要作用:ModelAndView为返回值视图控制
@Component
public class MyExceptionHandle  implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView modelAndView = new ModelAndView();
        // 默认
        System.out.println(e.getCause());
        System.out.println(e.getMessage());
        System.out.println(e.getStackTrace());
        modelAndView.setViewName("error.jsp");
        return modelAndView;
    }
}
  1. 注解方式:使用@ControllerAdvice+@ExceptionHandler来处理,异常处理器:异常处理器指定要处理的异常类型包括自定义异常,最后控制视图或响应体(常用)
    主要作用:既可以控制视图,也可以响应体方式返回异常
@ControllerAdvice
public class ExceptionHandle {
 // 视图
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ModelAndView exceptionHandle(Exception ex){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("error.jsp");
        return mv ;
    }
// 自定义异常
    @ExceptionHandler(MyException.class)
    @ResponseBody
    public Result returnErrStr(MyException ex) throws JsonProcessingException {
        Result  result=new Result();
        result.setCode(ex.getCode());
        result.setMsg(ex.getMsg());
        return result ;
    }
    // 异常类型
    @ExceptionHandler(IOException.class)
    @ResponseBody
    public String returnErr(Exception ex){
        String str="{\"code\":\"1\",\"msg\":\""+ex.getMessage()+"\"}";
        return str ;
    }
}

@ControllerAdvice
public class ExceptionHandle {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ModelAndView exceptionHandle(Exception ex){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("error.jsp");
        return mv ;
    }

    @ExceptionHandler(IOException.class)
    @ResponseBody
    public String returnErr(Exception ex){
        String str="{\"code\":\"1\",\"msg\":\""+ex.getMessage()+"\"}";
        return str ;
    }
}

补充

设置字符编码:

 <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>

其他+视图解析器

配置自定掃描包:  
 <context:component-scan base-package="com.xusx"></context:component-scan>.
 配置Spring注解:  
    <context:annotation-config></context:annotation-config>
 配置切面注解:  
    <aop:aspectj-autoproxy expose-proxy="false"></aop:aspectj-autoproxy>
 配置静态资源访问注解:  
    <mvc:default-servlet-handler></mvc:default-servlet-handler>
 配置springmvc注解:  
    <mvc:annotation-driven></mvc:annotation-driven>
配置spring視圖解析器:   
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
						<property name="prefix" value="/WEB-INF/views/"></property>      前缀
						<property name="suffix" value=".jsp"></property>                  后缀
 </bean>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值