我的SpringMVC学习

spring MVC

SpringMVC 是一种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级 Web 框架,属于 SpringFrameWork 的后续产品,已经融合在 Spring Web Flow 里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用 Spring 进行 WEB 开发时,可以选择使用 Spring的 Spring MVC 框架或集成其他 MVC 开发框架,如 Struts1(现在一般不用),Struts2 等。SpringMVC 已经成为目前最主流的 MVC 框架之一,并且随着 Spring3.0 的发布,全面超越 Struts2,成为最优秀的 MVC 框架。它通过一套注解,让一个简单的 Java 类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful 编程风格的请求

本质:SpringMVC就是将Servlet进行了封装,提供一个公共的Servlet。该Servlet可以根据请求动态的调用对应的逻辑方法完成请求处理

优点:

1、清晰的角色划分:

​ 前端控制器(DispatcherServlet)

​ 请求到处理器映射(HandlerMapping)

​ 处理器适配器(HandlerAdapter)

​ 视图解析器(ViewResolver)

       处理器或页面控制器(Controller)

​ 验证器( Validator)

​ 命令对象(Command 请求参数绑定到的对象就叫命令对象)

​ 表单对象(Form Object 提供给表单展示和提交到的对象就叫表单对象)。

2、分工明确,而且扩展点相当灵活,可以很容易扩展,虽然几乎不需要。

3、由于命令对象就是一个 POJO,无需继承框架特定 API,可以使用命令对象直接作为业务对象。

4、和 Spring 其他框架无缝集成,是其它 Web 框架所不具备的。

5、功能强大的数据验证、格式化、绑定机制。

6、利用 Spring 提供的 Mock 对象能够非常简单的进行 Web 层单元测试。

7、本地化、主题的解析的支持,使我们更容易进行国际化和主题的切换。

8、强大的 JSP 标签库,使 JSP 编写更容易。

9、RESTful风格的支持、简单的文件上传、约定大于配置的契约式编程支持、基于注解的零配置支持等等。

spring MVC解决问题

  1. 每个功能都要声明对应Servlet,比较麻烦
  2. 在Servlet中获取请求数据比较麻烦
  3. 响应的方式的代码,声明响应数据

MVC 模型

M: Model

模型层. 负责跟数据库进行交互的操作. pojo, service, dao(mapper)

V:View

视图层. 进行数据的表现. 负责跟客户进行交互. jsp, html, css, js, …

C:Controller

控制器层. 桥梁. 负责M和V之间的交互.

SpringMVC执行原理

  1. 用户(前台)发送请求到DispatcherServlet(前端控制器)
  2. 前端控制器收到请求后调用HandlerMapper(处理器映射器)
  3. 处理器根据请求的url地址找到具体的Handler(处理器),生成处理器对象及拦截器(如果有就生成)一并返回处理器执行链给DispatcherServlet
  4. DispatcherServlet通过HandlerAdapter(处理器适配器)调用处理器
  5. 执行Handler(处理器),也就是Controller,也叫后端控制器
  6. Handler执行完,返回ModelAndView
  7. 处理器适配器HandlerAdapter将Controller执行结果ModelAndView返回给DispatcherServlet
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(将模型数据填充到视图中)
  11. DispatcherServlet响应结果(页面)给前台用户

在这里插入图片描述

SpringMVC 注解

@Controller

用于描述控制层类注解

@RequestMapping

处理请求地址映射

@RequestMapping注解中属性:

  • value : 指定请求的实际地址,指定的地址可以是具体地址、可以RestFul动态获取,也可以使用正则设置
  • method : 指定请求的method类型, 分为GET、POST、PUT、DELETE等
  • params : 指定request中必须包含某些参数值是,才让该方法处理
  • produces : 指定返回的内容类型
  • headers : 指定request中必须包含某些指定的header值,才能让该方法处理请求
@RequestMapping(value = {"/demo1", "a", "b"}, method = RequestMethod.GET,params = {"name=zs"}, headers = {"Accept"}, produces = {"text/html;charset=UTF-8"})
public String demo1() {
    return "success.jsp";
}

@PostMapping

处理Post请求地址映射 ,属性跟@RequestMapping注解类似

@PostMapping("/testPost")
public String testPost(@RequestParam(required = false) String name){
    System.out.println(name);
    return "success.jsp";
}

@GetMapping

处理Get地址映射 ,属性跟@RequestMapping注解类似

@GetMapping("/testGet")
public String testGet(String name){
    System.out.println(name);
    return "success.jsp";
}

@RequestParam

处理请求参数名

@RequestParam注解属性:

  • value / name : 请求参数中名称
  • required : 请求参数中是否必须提供此参数,默认为true,true为必须提供
  • defaultValue :请求参数默认值
@RequestMapping("/demo2")
public String demo2(@RequestParam(value = "uname",
required = true, defaultValue = "zs") String name) {
    System.out.println(name);
    return "success.jsp";
}

@PathVariable

用于绑定url中的占位符,处理REST(请求数据作为请求地址的一部分发送给后台的方式)

 /**
   * @PathVariable 用于绑定url中的占位符
   * 测试:http://localhost:8080/demo3/lisi/123/11
   */
@RequestMapping("/demo3/{name}/{pwd}/{uu}")
public String demo3(@PathVariable(value = "name", required = true) Stringaname,
@PathVariable String pwd, @PathVariable String uu) {
    System.out.println(aname + "---" + pwd + "---" + uu);
    return "/success.jsp";
}

@ResponseBody

获取响应体内容,给前端

例如将对象转为json字符响应给前端

@RequestMapping(value = "/testBo",produces = {"application/json;charset=utf-8"})
@ResponseBody
public List<String> test(){
    List list = new ArrayList<>();
    Collections.addAll(list,"1111","2222","3333");
    System.out.println(list);
    return list;
}

@RestController

相当于*@ResponseBody+@Controller*

@RequestBody

用于获取请求体内容。直接使用得到是 key=value&key=value…结构的数据,get 请求方式不适用

@RequestMapping("/testRequestBody")
public String useRequestBody(@RequestBody(required=false) String body){
System.out.println(body);
return "success.jsp";
}

@RequestHeader

用于获取请求消息头

/**
  * @RequestHeader 获取请求头信息
  * 获取请求头包含Accept信息 
  * 测试:http://localhost:8080/demo4?h=1
  */
@RequestMapping("/demo4")
public String demo4(@RequestHeader(value = "Accept") String h) {
    //String accept = request.getHeader("Accept");
    System.out.println(h);
    return "/success.jsp";
}

@CookieValue

用于把指定 cookie 名称的值传入控制器方法参数

@RequestMapping("/demo5")
public String demo5(@CookieValue(value = "JSESSIONID") String h, HttpServletRequest request) {
    Cookie[] cookies = request.getCookies();
    boolean jsessionid = cookies[0].getName().equals("JSESSIONID");
    cookies[0].getValue();
    System.out.println(h);
    System.out.println(jsessionid);
    return "/success.jsp";
}

@JsonFormat

处理响应json格式 数据的处理

@JsonFormat的属性:

  • pattern :指定响应时间日期的格式
  • Timezone:指定响应的时区
public class TestA {
    @JsonFormat(pattern = "yyyy-MM-DD",timezone = "GTM+8")
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}
@ResponseBody
@RequestMapping(value = "/testJsonFor",produces = {"application/json;charset=utf-8"})
public TestA testJsonFor(TestA test){
    System.out.println(test);
    return  test;
}

@CrossOrigin

解决ajax请求之间的跨域问题

@CrossOrigin注解的属性:

  • origins :允许可访问的域列表
  • maxAge :准备响应前的缓存持续的最大时间(以秒为单位)

SpringMVC 转发和重定向

方式一(推荐):使用字符串

/**
  * 测试:
  * http://localhost:8080/MyController/testStringForward
  */
@RequestMapping("/testStringForward")
public String testStringForward(){
    /*转发*/
    return "forward:/success.jsp";
}

/**
  * 测试:
  * http://localhost:8080/MyController/testStringRedirect
  */
@RequestMapping("/testStringRedirect")
public String testStringRedirect(){
    /*重定向*/
    return "redirect:/success.jsp";
}

方式2:使用View


/**
  * 测试: 
  * http://localhost:8080/MyController/testViewForward
  */
@RequestMapping("/testViewForward")
public View testViewForward() {
    //转发
    View v = new InternalResourceView("/success.jsp");
    return v;
}
/**
  * 测试: 
  * http://localhost:8080/MyController/testViewRedirect
  */
@RequestMapping("/testViewRedirect")
public View testViewRedirect() {
    //重定向
    View v = new RedirectView("/success.jsp");
    return v;
}

方式3:使用ModelAndView

/**
  * 测试:
  * http://localhost:8080/MyController/testForward
  */
@RequestMapping("/testForward")
public ModelAndView testForward() {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("msg", "提示信息");
    //转发
    modelAndView.setView(new InternalResourceView("/success.jsp"));
    //modelAndView.setViewName("forward:/success.jsp");
    return modelAndView;
}

/**
  * 测试: 
  * http://localhost:8080/MyController/testRedirect
  */
@RequestMapping("/testRedirect")
public ModelAndView testRedirect() {
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("msg", "提示信息");
    modelAndView.setView(new RedirectView("/success.jsp"));
    //modelAndView.setViewName("redirect:/success.jsp");

    return modelAndView;
}

拦截器

对用户请求进行拦截处理,控制器响应拦截处理

和Servlet过滤器的区别:

过滤器是对所有请求进行处理,springMVC的拦截器针对的是控制单元(Controller类中的方法)

拦截器能实现的功能,过滤器都能实现,过滤器能实现的功能,拦截器不一定能实现

配置拦截器

<!--配置拦截器-->
<mvc:interceptors>
    <bean id="inter2" class="com.test.interceptor.MyInterceptorB"></bean>
    <!--定义拦截器的配置  path前面的/一定要加上-->
    <mvc:interceptor>
        <mvc:mapping path="/login"/>
        <bean id="inter1" class="com.test.interceptor.MyInterceptorA"></bean>
    </mvc:interceptor>
</mvc:interceptors>
package com.test.interceptor;

public class MyInterceptorA implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println("preHandle-------A");
        return true;
    }

    //执行的时机:在控制单元中做出相应之前 ,也就是在控制单元中第二步和第三步之间
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        System.out.println("postHandle-------A");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

        System.out.println("afterCompletion-------A");
    }
}

异常处理

作用:当代码运行出现异常,响应错误页面

配置xml文件 注解扫描

<!--注解扫描-->
<context:component-scan base-package="com.test.controller,com.test.exceptionM"></context:component-scan>

方式1:@ExceptionHandler

缺点:只能处理当前Controller中的异常

@ExceptionHandler(value = {ArithmeticException.class})
public ModelAndView  handlerArithmeticException(){

    System.out.println("局部");

    ModelAndView  modelAndView=new ModelAndView();

    modelAndView.setViewName("redirect:/error.jsp");

    return  modelAndView;
}

方式2: 使用@ControllerAdvice+@ExceptionHandler

全局异常处理器

package com.test.exceptionM;
//全局异常处理操作
@ControllerAdvice
public class GloableException {
    @ExceptionHandler(value = {ArithmeticException.class})
    public ModelAndView handlerArithmeticException(){
        System.out.println("全局");
        ModelAndView  modelAndView=new ModelAndView();
        modelAndView.setViewName("redirect:/error.jsp");
        return  modelAndView;
    }
}

方式3:@Configuration+@Bean + SimpleMappingExceptionResolver

SimpleMappingExceptionResolver

/**全局异常处理方式   这种方式就是为了代替我们之前xml 的配置*/
@Configuration
public class GloableException2 {
    @Bean
    public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver(){
        SimpleMappingExceptionResolver  resolver=new SimpleMappingExceptionResolver();
        //存放异常类型和跳转页面
        Properties   properties=new Properties();
        properties.put("java.lang.ArithmeticException","redirect:/errpe.jsp");
        resolver.setExceptionMappings(properties);
        return   resolver;
    }
}

方式4:实现HandlerExceptionResolver接口

@Configuration
public class GloableException3 implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView  modelAndView=new ModelAndView();
        if(e instanceof ArithmeticException){
            modelAndView.setViewName("redirect:/error.jsp");
        }else  if(e instanceof NullPointerException){
            modelAndView.setViewName("redirect:/error2.jsp");
        }
        return modelAndView;
    }
}

方式4:实现HandlerExceptionResolver接口

@Configuration
public class GloableException3 implements HandlerExceptionResolver {
    @Override
    public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
        ModelAndView  modelAndView=new ModelAndView();
        if(e instanceof ArithmeticException){
            modelAndView.setViewName("redirect:/error.jsp");
        }else  if(e instanceof NullPointerException){
            modelAndView.setViewName("redirect:/error2.jsp");
        }
        return modelAndView;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值