栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

SpringMVC之使用与原理

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

SpringMVC之使用与原理

SpringMVC之使用与原理
  • 前言
  • 一、初窥门径
  • 二、小试牛刀
    • 1.引入依赖
    • 2.创建Spring和SpringMVC的配置文件
      • 2.1 Spring配置文件
      • 2.2 SpringMVC配置文件
    • 3.web.xml配置
    • 4.编写Controller
    • 5.编写个页面
    • 6.启动tomcat
  • 三、粗通皮毛
    • 1.SpringMVC的工作流程
    • 2.SpringMVC组件
    • 3.web.xml中url-pattern解析
    • 4.常用注解
    • 5.中文乱码
  • 四、登堂入室
    • 1.处理器接收参数
      • 1.1 直接使用方法的参数逐个接收
    • 1.2 使用对象接收多个参数
    • 1.3 使用原生HttpServletRequest获取
    • 1.4 获取日期类型的参数
    • 1.5 获取数组类型的参数
    • 1.6 获取List类型的参数
    • 1.7使用URL地址传参
    • 2.处理器方法返回值
      • 2.2 返回String
      • 2.3 返回对象类型
        • 2.3.1 返回基本类型
      • 2.4 返回void
    • 3. 转发和重定向
      • 3.1 转发
      • 3.2 重定向
    • 4.异常处理
      • 4.1 自定义异常类
    • 5. 拦截器
    • 6.文件上传和下载
      • 6.1.文件上传
    • 6.2 下载


前言 SpringMVC 也叫 Spring web mvc。是 Spring内置的一个MVC框架,在 Spring3.0 后发布。SpringMVC 框架解决了WEB开发中常见的问题(参数接收、文件上传、表单验证等等),而且使用简单,与Spring无 缝集成。支持 RESTful风格的URL请求。采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性 和灵活性。
一、初窥门径 在没有使用SpringMVC之前我们都是使用Servlet在做Web开发。但是使用Servlet开发在接收请求参数,数据共享,页面跳转等操作相对比较复杂。servlet是java进行web开发的标准,既然springMVC是对servlet的封装,那么很显然**SpringMVC底层就是Servlet,SpringMVC就是对Servlet进行深层次的封装。** 二、小试牛刀 1.引入依赖


    4.0.0

    springmvckkb
    com.dmlll.mvc
    1.0-SNAPSHOT
    war
    
        
            org.springframework
            spring-webmvc
            5.2.15.RELEASE
        
        
            javax.servlet
            javax.servlet-api
            4.0.1
            provided
        
    
    
        
            
                org.apache.maven.plugins
                maven-compiler-plugin
                3.8.1
                
                    1.8
                    1.8
                
            
            
            
                org.apache.tomcat.maven
                tomcat7-maven-plugin
                2.2
                
                    8080
                    /
                
            
        
    

SpringMVC依赖了Spring,如果对版本没有要求,不必再导入Spring

2.创建Spring和SpringMVC的配置文件 2.1 Spring配置文件


    

2.2 SpringMVC配置文件



    
    
    

3.web.xml配置


         
    
        contextConfigLocation
        classpath:application.xml
    
    
        org.springframework.web.context.ContextLoaderListener
    
    
    
        dispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            classpath:springmvc.xml
        
        1
    
    
        dispatcherServlet
        *.do
    


4.编写Controller
@Controller
public class TestController {
    @RequestMapping("hello.do")
    public ModelAndView hello(){
        String str = "欲练此功,必先自宫";
        System.out.println(str);
        ModelAndView mv = new ModelAndView();
        mv.addObject("word",str);
        mv.setViewName("hello");
        return mv;
    }
}
5.编写个页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    ${word}


6.启动tomcat

因为配置了插件,可以直接在maven中启动

三、粗通皮毛 1.SpringMVC的工作流程

  1. 浏览器发送请求,DispatchServlet接收到浏览器发送的请求
	
        dispatcherServlet
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            classpath:springmvc.xml
        
        1
    
    
        dispatcherServlet
        *.do
    
  1. DispatchServlet接收到请求后转交给HandlerMapping
  2. HandlerMapping根据请求找到对应的处理器,并将其封装成一个处理器执行链(包括处理器Handler、处理器拦截器HandlerInterceptor)返回给DispatchServlet
  3. DispatchServlet根据Handler找到对应的HandlerAdaptor,HandlerAdaptor经过参数封装/数据格式转换等一系列操作。
  4. HandlerAdaptor执行Controller中的方法
  5. Controller返回ModelAndView
  6. HandlerAdaptor将ModelAndView返回给DispatchServlet
  7. DispatchServlet将ModelAndView交给ViewResolve进行解析
  8. ViewResolve将解析后得到的View返回给DispatchServlet
  9. DispatcherServlet调用视图对象进行渲染,得到响应对象
  10. 将响应对象返回给浏览器
    代码如下(示例):
2.SpringMVC组件
  1. DispatcherServlet:前端控制器
    用户请求的入口控制器,DispatcherServlet是整个流程控制的中心,由他调用其他组件处理用户的请求。DispatcherServlet降低了各组件之间的耦合性。
  2. HandlerMapping:处理器映射器
    HandlerMapping是派发请求的控制器。负责根据用户的请求找到Handler。
  3. Handler:处理器
    Handler即Controller,由程序员根据需求编写
  4. HandlerAdaptor:处理器适配器
    负责调用处理器、传递参数等工作。
  5. VIewResolver:视图解析器
    ViewResolver负责将处理结果生成View视图。ViewResolver首先根据逻辑视图名称(相对)解析成物理视图名称(绝对),在生成View视图对象,最后对View进行渲染,将处理结果展示给用户。
3.web.xml中url-pattern解析
	
        dispatcherServlet
        *.do
    

该节点一般有两种写法:

  1. *.xx
    在没有特殊要求的情况下,SpringMVC的前端控制器常使用后缀匹配方式
  2. /
    该种方式是让所有的请求都经过前端控制器,去找对应的处理器。但是静态文件不会去编写处理器,所以就需要去配置静态资源的放行

DefaultServlet。位与tomcat安装目录/conf/web.xml中
-->



4.常用注解
  1. @RequestMapping
    定义了处理器对于请求的映射规则,即请求路径。可以作用与类和方法
  2. @ResponseBody
    将返回的数据结构转换为JSON格式
  3. @PathVariable
    用来获取路径中的参数
    http://localhost:8080/user/{id}
  4. @RequestParam
    用于获取请求的参数
    http://localhost:8080/user?id=1
  5. @RequestBody
    用于POST请求上,接受JSON实体参数
  6. @ControllerAdvice
    Controller增强器,给Controller控制器添加统一的操作或处理
5.中文乱码

Spring对于请求参数中的中文乱码问题,给出了专门的CharacterEncodingFilter类,在web.xml中配置

	
        characterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            utf-8
        
    
    
        characterEncodingFilter
        /*
    

可进入该类查看对应的参数:

如果使用的是maven中的tomcat插件,还应该去配置tomcat的字符集


    org.apache.tomcat.maven
    tomcat7-maven-plugin
    2.2
    
        8080
        /
        utf-8
    

四、登堂入室 1.处理器接收参数

编写传递参数的页面params.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    处理参数


ID:
姓名:
地址:

编写请求结束跳转的页面ok.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    ${id},${name},${address}


编写实体类Person.java

public class Person {
    private Integer id;
    private String name;
    private String address;
	//setter/getter/toString
}

编写页面跳转的控制器ParamsController.java

@Controller
@RequestMapping("params")
public class ParamsController {

    @RequestMapping("view.do")
    public ModelAndView view(){
        System.out.println("进入params页面");
        return new ModelAndView("params");
    }
}    
1.1 直接使用方法的参数逐个接收

注意:参数名必须和前端传过来的名称一致
向ParamsController.java中添加方法

@RequestMapping("get1.do")
public ModelAndView get1(Integer id,String name,String address){
    System.out.println(id + "---" + name + "---" + address);
    ModelAndView mv = new ModelAndView("ok");
    mv.addObject("id",id);
    mv.addObject("name",name);
    mv.addObject("address",address);
    return mv;
}

运行:

1.2 使用对象接收多个参数

注意:对象的属性必须和前端传过来的参数名称一致
向ParamsController.java中添加方法

@RequestMapping("get2.do")
public ModelAndView get2(Person person){
    System.out.println(person.getId() + "---" + person.getName() + "---" + person.getAddress());
    ModelAndView mv = new ModelAndView("ok");
    mv.addObject("person",person);
    return mv;
}

修改params.jsp中的表单

ID:
姓名:
地址:

修改ok.jsp接收参数的变量

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


    ${person.id},${person.name},${person.address}


运行:

1.3 使用原生HttpServletRequest获取

向ParamsController.java中添加方法

@RequestMapping("get3.do")
public ModelAndView get3(HttpServletRequest request){
    String id = request.getParameter("id");
    String name = request.getParameter("name");
    String address = request.getParameter("address");
    System.out.println(id + "---" + name + "---" + address);
    ModelAndView mv = new ModelAndView("ok");
    //封装成Person
    Person person = new Person();
    person.setId(Integer.valueOf(id));
    person.setName(name);
    person.setAddress(address);
    mv.addObject("person",person);
    return mv;
}

修改params.jsp的form路径

运行:

1.4 获取日期类型的参数

直接接收会报错
修改Person.java,添加时间属性

private Date date;

修改params.jsp,添加时间选择框

日期:

运行:


需要在date属性上添加注解@DateTimeFormat(pattern = “yyyy-MM-dd”)
再次启动:

1.5 获取数组类型的参数

修改ParamsController.java

@RequestMapping("get4.do")
public ModelAndView get4(String[] names){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("names",names);
    modelAndView.setViewName("ok");
    return modelAndView;
}

修改params.jsp表单


    姓名1:
姓名2:
姓名3:

修改ok.jsp

 ${name[0]},${name[1]},${name[2]}

运行:

1.6 获取List类型的参数

集合类型不能直接接收

修改ParamsController.java

@RequestMapping("get5.do")
public ModelAndView get5(List name){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("names",names);
    modelAndView.setViewName("ok");
    return modelAndView;
}

修改params.jsp

此时运行:

需要在集合参数上添加@RequestParam()注解

@RequestMapping("get5.do")
public ModelAndView get5(@RequestParam(value = "names") List names){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("names",names);
    modelAndView.setViewName("ok");
    return modelAndView;
}

再次启动一切正常。

如果将List换成List
再次启动
(此时name属性与Person中的name属性对应,如果正常,则只有Person.name有值)

提示List中的name不存在,因此不能直接使用List去接受对象集合,将集合封装成一个对象ListVO

public class ListVO {
    private List list;

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }
}

修改ParamsController.java

@RequestMapping("get6.do")
public ModelAndView get6(ListVO vo){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("names",vo.getNameList());
    modelAndView.setViewName("ok");
    return modelAndView;
}

修改params.jsp


    姓名1:
姓名2:
姓名3:

启动程序:

注意:前端参数列表的参数名必须跟该ListVO对象的属性一致

1.7使用URL地址传参

修改ParamController.java

@RequestMapping("get7/{id}.do")
public ModelAndView get7(@PathVariable("id") Integer id){
    ModelAndView modelAndView = new ModelAndView("ok");
    modelAndView.addObject("id",id);
    return modelAndView;
}

修改ok.jsp

  ${id}

直接在地址栏输入
http://localhost:8080/params/get7/1.do
因为在配置文件中配置的*.do,只有.do为后缀的才能被拦截到,所以采用了这种方式@RequestMapping(“get7/{id}.do”)

2.处理器方法返回值

处理器返回值有四种类型:

  1. ModelAndView
  2. String
  3. 返回自定义类型对象
  4. 无返回值void

ModelAndView在上一节已经使用。

2.2 返回String
@RequestMapping("get8.do")
public String get8(){
    return "ok";
}

如果携带参数可携带HttpServletRequest ,通过原生的方法传递参数

2.3 返回对象类型 2.3.1 返回基本类型
@RequestMapping("get9.do")
@ResponseBody
public String get9(){
    return "xiaoming";
}

引入JSON依赖


    com.fasterxml.jackson.core
    jackson-core
    2.12.4


    com.fasterxml.jackson.core
    jackson-databind
    2.12.4

@RequestMapping("get9.do")
@ResponseBody
public Person get9(){
    Person p = new Person();
    p.setAddress("东莞");
    p.setName("超级玛丽");
    p.setId(1);
    return p;
}

2.4 返回void

使用原生的HttpServletRequest、HttpServletResponse

3. 转发和重定向 3.1 转发
@RequestMapping("get11.do")
public String get11(){
    return "forward:/ok.jsp";
}
@RequestMapping("get12.do")
public ModelAndView get12(){
    return new ModelAndView("forward:/ok.jsp");
}
3.2 重定向
@RequestMapping("get13.do")
public String get13(){
    return "redirect:/ok.jsp";
}
@RequestMapping("get14.do")
public ModelAndView get14(){
    return new ModelAndView("redirect:/ok.jsp");
}

一般的重定向不会传递参数,SpringMVC中的重定向可以传递参数,以?key=value的形式拼接

4.异常处理

使用@ExceptionHandler注解,指定为异常处理的方法。
返回值可以是:ModelAndView、String、void
参数可以是:Exception及其子类、HttpServletRequest、HttpServletResponse等,系统会自动为其赋值

4.1 自定义异常类
public class MyException extends Exception{
    public MyException() {
    }

    public MyException(String message) {
        super(message);
    }
}

ParamsController.java

@RequestMapping("get16.do")
public ModelAndView get16() throws MyException {
    throw new MyException("就故意报错");//抛出异常
}
@ExceptionHandler(value= MyException.class)
public ModelAndView get15(Exception ex){
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.setViewName("ok");
    modelAndView.addObject("msg",ex.getMessage());
    return modelAndView;
}

修改ok.jsp

${msg}

运行

也可以通过@ControllerAdvice注解将异常处理方法统一管理

@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(value = ArithmeticException.class)
    public ModelAndView exception01(ArithmeticException ex){
        ModelAndView ok = new ModelAndView("ok");
        ok.addObject("msg",ex.getMessage());
        return ok;
    }
    @ExceptionHandler(value = Exception.class)
    public ModelAndView exception02(Exception ex){
        ModelAndView ok = new ModelAndView("ok");
        ok.addObject("msg",ex.getMessage());
        return ok;
    }
}
5. 拦截器

主要作用:拦截用户的请求,进行相应的预处理和后处理
如何实现:实现HandlerInterceptor接口,重写其方法

public class MyInterceptor implements HandlerInterceptor {
	//在处理器方法执行之前执行,返回值为true,放行拦截的方法,
	//将afterCompletion方法放入一个专门的方法栈等待
	//返回值为false,被拦截的方法则不执行
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return false;
    }
	//该方法在处理器方法执行之后,返回结果之前,该方法可以改变处理器方法的处理结果和跳转的页面
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }
	//preHandle方法返回true时,在处理器方法返回结果之后,执行该方法
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

配置拦截器


    
        
        
    

编写拦截器代码

public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("预处理-----------");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("处理中-----------");
        System.out.println("替换处理器存储的msg");
        request.setAttribute("msg","你被替换了");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("后处理-----------");
    }
}

编写处理器

@RequestMapping("get17.do")
public String get17(HttpServletRequest request)  {
    System.out.println("处理器方法执行存储");
    request.setAttribute("msg","我是1");
    return "ok";
}

6.文件上传和下载 6.1.文件上传

SpringMVC为文件上传提供了直接支持,即通过MultipartResolver实现
Spring中有一个实现类CommonsMultipartResolver
在SpringMVC上下文中默认没有装配MultipartResolver,需要先在配置文件中配置


引入依赖


    commons-fileupload
    commons-fileupload
    1.4

编辑页面进行文件上传

文件:

编写处理器

@RequestMapping("get18.do")
public String get18(@RequestParam("file") MultipartFile file,HttpServletRequest request) throws IOException {
    String originalFilename = file.getOriginalFilename();//原始文件名
    //获取后缀
    String suffix = originalFilename.substring(originalFilename.lastIndexOf("."));
    //组成随机名称
    String filename = UUID.randomUUID().toString().replace("-","")+suffix;
    request.setAttribute("filename",filename);
    //存储路径
    String path = request.getServletContext().getRealPath("/upload") + "/";
    file.transferTo(new File(path,filename));
    System.out.println("上传成功");
    return "ok";
}

新建upload文件夹

修改ok.jsp


运行:

6.2 下载
@RequestMapping("get19.do")
public ResponseEntity get19(HttpServletRequest request) throws IOException {
    //指定路径
    String path = request.getServletContext().getRealPath("/upload")+"/566e00bb19a8430e85beeafd4c27697a.jpg";
    //创建响应的头信息
    HttpHeaders headers = new HttpHeaders();
    //以流的形式打开
    headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    //以附件形式响应给用户
    headers.setContentDispositionFormData("attachment", URLEncoder.encode("566e00bb19a8430e85beeafd4c27697a.jpg","utf-8"));
    File file = new File(path);
    ResponseEntity responseEntity = new ResponseEntity(FileUtils.readFileToByteArray(file),headers, HttpStatus.CREATED);
    return responseEntity;
}

SpringMVC之使用与原理
下载

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/439541.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号