ErBing

往事已经定格,未来还要继续。

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

 

一.SpringMVC 简介
1.SpringMVC 中重要组件
  1.1 DispatcherServlet : 前端控制器,接收所有请求(如果配置/不包含 jsp)
  1.2 HandlerMapping: 解析请求格式的.判断希望要执行哪个具体的方法.
  1.3 HandlerAdapter: 负责调用具体的方法.
  1.4 ViewResovler:视图解析器.解析结果,准备跳转到具体的物理视图
2.SpringMVC 运行原理图

3.Spring 容器和 SpringMVC 容器的关系

  3.1 代码

  

  3.2 Spring 容器和 SpringMVC 容器是父子容器.
    3.2.1 SpringMVC 容器中能够调用 Spring 容器的所有内容.
    3.2.2 图示

    

二.SpringMVC 环境搭建
  1. 导入 jar

  

2. 在 web.xml 中配置前端控制器 DispatcherServlet
  2.1 如 果 不 配 置 <init-param> 会 在/WEB-INF/<servlet-name>-servlet.xml

<servlet>
    <servlet-name>jqk</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>jqk</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>    

3. 在 src 下新建 springmvc.xml
  3.1 引入 xmlns:mvc 命名空间

<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
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.bjsxt.controller"></context:component-scan>
<!-- 注解驱动 -->
<!--
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandler
Mapping -->
<!--
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerA
dapter -->
<mvc:annotation-driven></mvc:annotation-driven>
<!-- 静态资源 -->
<mvc:resources location="/js/" mapping="/js/**"></mvc:resources>
<mvc:resources location="/css/" mapping="/css/**"></mvc:resources>
<mvc:resources location="/images/"
mapping="/images/**"></mvc:resources>
</beans>

4. 编写控制器类

@Controller
public class DemoController {
    @RequestMapping("demo")
    public String demo(){
        System.out.println("执行 demo");
        return "main.jsp";
    }
    @RequestMapping("demo2")
    public String demo2(){
        System.out.println("demo2");
        return "main1.jsp";
    }
}

三. 字符编码过滤器
1.在 web.xml 中配置 Filter

<!-- 字符编码过滤器 -->
<filter>
    <filter-name>encoding</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>
</filter>
<filter-mapping>
    <filter-name>encoding</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

四.传参
1. 把内容写到方法(HandlerMethod)参数中,SpringMVC 只要有这个内容,注入内容.
2. 基本数据类型参数
  2.1 默认保证参数名称和请求中传递的参数名相同

@Controller
public class DemoController {
    @RequestMapping("demo")
    public String demo(String name,int age){
        System.out.println("执行 demo"+" "+name+""+age);
        return "main.jsp";
    }
}

  2.2 如果请求参数名和方法参数名不对应使用@RequestParam()赋值

@RequestMapping("demo")
public String demo(@RequestParam(value="name1") String name,@RequestParam(value="age1")int age){
    System.out.println("执行 demo"+" "+name+""+age);
    return "main.jsp";
}

  2.3 如果方法参数是基本数据类型(不是封装类)可以通过@RequestParam 设置默认值.
    2.3.1 防止没有参数时 500

@RequestMapping("page")
public String page(@RequestParam(defaultValue="2") int pageSize,@RequestParam(defaultValue="1") int pageNumber){
    System.out.println(pageSize+" "+pageNumber);
    return "main.jsp";
}

  2.4 如果强制要求必须有某个参数

@RequestMapping("demo2")
public String demo2(@RequestParam(required=true) String name){
    System.out.println("name 是 SQL 的查询条件,必须要传递 name 参数"+name);
    return "main.jsp";
}

3. HandlerMethod 中参数是对象类型
  3.1 请求参数名和对象中属性名对应(get/set 方法)

@RequestMapping("demo4")
public String demo4(People peo){
    return "main.jsp";
}

4. 请求参数中包含多个同名参数的获取方式
  4.1 复选框传递的参数就是多个同名参数

@RequestMapping("demo5")
public String demo5(String name,int age,@RequestParam("hover")List<String> abc){
    System.out.println(name+" "+age+" "+abc);
    return "main.jsp";
}

5. 请求参数中对象.属性格式
  5.1 jsp 中代码

<input type="text" name="peo.name"/>
<input type="text" name="peo.age"/>

  5.2 新建一个类
    5.2.1 对象名和参数中点前面名称对应

public class Demo {
private People peo;

  5.3 控制器

@RequestMapping("demo6")
public String demo6(Demo demo){
    System.out.println(demo);
    return "main.jsp";
}

6. 在请求参数中传递集合对象类型参数
  6.1 jsp 中格式

<input type="text" name="peo[0].name"/>
<input type="text" name="peo[0].age"/>
<input type="text" name="peo[1].name"/>
<input type="text" name="peo[1].age"/>

  6.2 新建类

public class Demo {
private List<People> peo;

  6.3 控制器

@RequestMapping("demo6")
public String demo6(Demo demo){
    System.out.println(demo);
    return "main.jsp";
}

7. restful 传值方式.
  7.1 简化 jsp 中参数编写格式
  7.2 在 jsp 中设定特定的格式

<a href="demo8/123/abc">跳转</a>

  7.3 在控制器中
    7.3.1 在@RequestMapping 中一定要和请求格式对应
    7.3.2 {名称} 中名称自定义名称
    7.3.3 @PathVariable 获取@RequestMapping 中内容,默认按照方法参数名称去寻找.

@RequestMapping("demo8/{id1}/{name}")
public String demo8(@PathVariable String name,@PathVariable("id1") int age){
    System.out.println(name +" "+age);
    return "/main.jsp";
}

五. 跳转方式
1. 默认跳转方式请求转发.
2. 设置返回值字符串内容
  2.1 添加 redirect:资源路径 重定向
  2.2 添加 forward:资源路径 或省略 forward: 转发

六. 视图解析器
1. SpringMVC 会提供默认视图解析器.
2. 程序员自定义视图解析器

<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/"></property>
    <property name="suffix" value=".jsp"></property>
</bean>

3. 如果希望不执行自定义视图解析器,在方法返回值前面添加forward:或 redirect:

 七.@ResponseBody

1. 在方法上只有@RequestMapping 时,无论方法返回值是什么认为需要跳转
2. 在方法上添加@ResponseBody(恒不跳转)
  2.1 如果返回值满足 key-value 形式(对象或 map)
    2.1.1 把响应头设置为 application/json;charset=utf-8
    2.1.2 把转换后的内容输出流的形式响应给客户端.
  2.2 如果返回值不满足 key-value,例如返回值为 String
    2.2.1 把相应头设置为 text/html
    2.2.2 把方法返回值以流的形式直接输出.
    2.2.3 如果返回值包含中文,出现中文乱码
    2.2.3.1 produces 表示响应头中 Content-Type 取值.

@RequestMapping(value="demo12",produces="text/html;charset=utf-8")
@ResponseBody
public String demo12() throws IOException{
    People p = new People();
    p.setAge(12);
    p.setName("张三");
    return "中文";
}

3. 底层使用Jackson进行json转换,在项目中一定要导入jackson的jar
  3.1 spring4.1.6 对 jackson 不支持较高版本,jackson 2.7 无效.

七.JSP 九大内置对象和四大作用域复习
1.九大内置对象

名称 类型 含义  获取方式
request HttpSevletRequest 封装所有请求信息 方法参数
response HttpServletResponse

封装所有响应信息

方法参数
session HttpSession 封装所有会话信息 req.getSession()
application ServletContext 所有信息

getServletContext();

request.getServletContext();

 out  PrintWriter  输出对象  

response.getWriter()

 exception  Exception  异常对象  
 page  Object  当前页面对象    
 pageContext  PageContext  获取其他对象    
 config  ServletConfig  配置信息  



2.四大作用域
  2.1 page
    2.1.1 在当前页面不会重新实例化.
  2.2 request
    2.2.1 在一次请求中同一个对象,下次请求重新实例化一个request 对象.
  2.3 session
    2.3.1 一次会话.
    2.3.2 只要客户端 Cookie 中传递的 Jsessionid 不变,Session 不会重新实力会(不超过默认时间.)
    2.3.3 实际有效时间:
        2.3.3.1 浏览器关闭.Cookie 失效.
        2.3.3.2 默认时间.在时间范围内无任何交互.在 tomcat 的web.xml 中配置

<session-config>
    <session-timeout>30</session-timeout>
</session-config>

  2.4 application
    2.4.1 只有在 tomcat 启动项目时菜实例化.关闭 tomcat 时销毁application

八.SpringMVC 作用域传值的几种方式
1. 使用原生 Servlet
  1.1 在 HanlderMethod 参数中添加作用域对象

@RequestMapping("demo1")
public String demo1(HttpServletRequest abc,HttpSession sessionParam){
    //request 作用域
    abc.setAttribute("req", "req 的值");
    //session 作用域
    HttpSession session = abc.getSession();
    session.setAttribute("session", "session 的值");
    sessionParam.setAttribute("sessionParam","sessionParam 的值");
    //appliaction 作用域
    ServletContext application = abc.getServletContext();
    application.setAttribute("application","application 的值");
    return "/index.jsp";
}

2. 使用 Map 集合
  2.1 把 map 中内容放在 request 作用域中
  2.2 spring 会对 map 集合通过 BindingAwareModelMap 进行实例化

@RequestMapping("demo2")
public String demo2(Map<String,Object> map){
    System.out.println(map.getClass());
    map.put("map","map 的值");
    return "/index.jsp";
}

3. 使用 SpringMVC 中 Model 接口
  3.1 把内容最终放入到 request 作用域中.

@RequestMapping("demo3")
public String demo3(Model model){
    model.addAttribute("model", "model 的值");
    return "/index.jsp";
}

4.使用 SpringMVC 中 ModelAndView 类

@RequestMapping("demo4")
public ModelAndView demo4(){
    //参数,跳转视图
    ModelAndView mav = new ModelAndView("/index.jsp");
    mav.addObject("mav", "mav 的值");
    return mav;
}

九. 文件下载
1.访问资源时相应头如果没有设置 Content-Disposition,浏览器默认按照 inline 值进行处理
  1.1 inline 能显示就显示,不能显示就下载.
2.只需要修改相应头中 Context-Disposition=”attachment;filename=文件名”
  2.1 attachment 下载,以附件形式下载.
  2.2 filename=值就是下载时显示的下载文件名
3.实现步骤
  3.1 导入 apatch 的两个 jar

  

  3.2 在 jsp 中添加超链接,设置要下载文件
    3.2.1 在 springmvc 中放行静态资源 files 文件夹

<a href="download?fileName=a.rar">下载</a>

  3.3 编写控制器方法

@RequestMapping("download")
public void download(String fileName,HttpServletResponse res,HttpServletRequest req) throws IOException{
    //设置响应流中文件进行下载
    res.setHeader("Content-Disposition","attachment;filename="+fileName);
    //把二进制流放入到响应体中.
    ServletOutputStream os = res.getOutputStream();
    String path =req.getServletContext().getRealPath("files");
    System.out.println(path);
    File file = new File(path, fileName);
    byte[] bytes =FileUtils.readFileToByteArray(file);
    os.write(bytes);
    os.flush();
    os.close();
}

十. 文件上传
1. 基于 apache 的 commons-fileupload.jar 完成文件上传.
2. MultipartResovler 作用:
  2.1 把客户端上传的文件流转换成 MutipartFile 封装类.
  2.2 通过 MutipartFile 封装类获取到文件流
3. 表单数据类型分类
  3.1 在<form>的 enctype 属性控制表单类型
  3.2 默认值 application/x-www-form-urlencoded,普通表单数据.(少量文字信息)
  3.3 text/plain 大文字量时使用的类型.邮件,论文
  3.4 multipart/form-data 表单中包含二进制文件内容.
4. 实现步骤:
  4.1 导入 springmvc 包和 apache 文件上传 commons-fileupload 和commons-io 两个 jar
  4.2 编写 JSP 页面

<form action="upload" enctype="multipart/form-data" method="post">
  姓名:<input type="text" name="name"/><br/>
  文件:<input type="file" name="file"/><br/>
  <input type="submit" value=" 提交 "/>
</form>

  4.3 配置 springmvc.xml

<!-- MultipartResovler 解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="50"></property>
</bean>
<!-- 异常解析器 -->
<bean id="exceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
    <property name="exceptionMappings">
        <props>
            <prop key="org.springframework.web.multipart.MaxUploadSizeExceededException">/error.jsp</prop>
        </props>
    </property>
</bean>

  4.4 编写控制器类
    4.4.1 MultipartFile 对象名必须和<input type=”file”/>的 name 属性值相同

@RequestMapping("upload")
public String upload(MultipartFile file,String name) throws IOException{
    String fileName = file.getOriginalFilename();
    String suffix =fileName.substring(fileName.lastIndexOf("."));
    //判断上传文件类型
    if(suffix.equalsIgnoreCase(".png")){
        String uuid = UUID.randomUUID().toString();
        FileUtils.copyInputStreamToFile(file.getInputStream(), new File("E:/"+uuid+suffix));
        return "/index.jsp";
    }else{
        return "error.jsp";
    }
}

十一. 自定义拦截器
1.跟过滤器比较像的技术.
2.发送 请求时被拦截器拦截,在控制器的前后添加额外功能.
  2.1 跟 AOP 区分开.AOP 在特定方法前后扩充(对 ServiceImpl)
  2.2 拦截器,请求的拦截.针对点是控制器方法.(对 Controller)
3.SpringMVC 拦截器和 Filter 的区别
  3.1 拦截器只能拦截器 Controller
  3.2 Filter 可以拦截任何请求.
4.实现自定义拦截器的步骤:
  4.1 新建类实现 HandlerInterceptor

public class DemoInterceptor implements HandlerInterceptor {
//在进入控制器之前执行
//如果返回值为 false,阻止进入控制器
//控制代码
@Override
public boolean preHandle(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2) throws Exception
{
    System.out.println("arg2:"+arg2);
    System.out.println("preHandle");
    return true;
}
//控制器执行完成,进入到 jsp 之前执行.
//日志记录.
//敏感词语过滤
@Override
public void postHandle(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {
    System.out.println("往"+arg3.getViewName()+"跳转");
    System.out.println("model 的值"+arg3.getModel().get("model"));
    String word =arg3.getModel().get("model").toString();
    String newWord = word.replace("祖国", "**");
    arg3.getModel().put("model", newWord);
    // arg3.getModel().put("model", "修改后的内容");
    System.out.println("postHandle");
}
//jsp 执行完成后执行
//记录执行过程中出现的异常.
//可以把异常记录到日志中
@Override
public void afterCompletion(HttpServletRequest arg0,HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {
    System.out.println("afterCompletion"+arg3.getMessage());
}
}

  4.2 在 springmvc.xml 配置拦截器需要拦截哪些控制器
    4.2.1 拦截所有控制器

<mvc:interceptors>
    <bean class="com.bjsxt.interceptor.DemoInterceptor"></bean>
</mvc:interceptors>

  4.2.2 拦截特定的的 url  

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/demo"/>
        <mvc:mapping path="/demo1"/>
        <mvc:mapping path="/demo2"/>
        <bean class="com.bjsxt.interceptor.DemoInterceptor"></bean>
    </mvc:interceptor>
</mvc:interceptors>

十二. 拦截器栈

1. 多个拦截器同时生效时,组成了拦截器栈
2. 顺序:先进后出.
3. 执行顺序和在 springmvc.xml 中配置顺序有关
4. 设置先配置拦截器 A 在配置拦截器 B 执行顺序为
preHandle(A) --> preHandle(B) --> 控制器方法 --> postHandle(B)
--> postHanle(A) --> JSP --> afterCompletion(B) --> afterCompletion(A)

 十三.SpringMVC 运行原理

1. 文字解释
如果在 web.xml 中设置 DispatcherServlet 的<url-pattern>为/时,当用户发 起 请 求 , 请 求 一 个 控 制 器 , 首 先 会 执 行 DispatcherServlet. 由
DispatcherServlet 调 用 HandlerMapping 的DefaultAnnotationHandlerMapping 解 析 URL, 解 析 后 调 用HandlerAdatper 组 件 的 AnnotationMethodHandlerAdapter 调 用
Controller 中的 HandlerMethod.当 HandlerMethod 执行完成后会返回View,会被 ViewResovler 进行视图解析,解析后调用 jsp 对应的.class 文件并运行,最终把运行.class 文件的结果响应给客户端.以上就是 springmvc 运行原理

posted on 2018-10-08 17:44  ErBing  阅读(506)  评论(0编辑  收藏  举报