Spring MVC

                                             Spring MVC

1. Spring MVC 概述

1.1. 企业级应用基本架构

企业级应用中的软件的分层的基本架构(参考阿里巴巴开发手册)

Spring MVC_第1张图片

 

说明:分层架构的本质是分而治之,已达到分解问题复杂性的目的,从而更好的进行设计与实现。

 

 

1.2. Web MVC架构及分析

基于servlet,jsp,javabean技术实现的MVC架构,具体架构图如下:

Spring MVC_第2张图片

 

1.3. Spring MVC 架构及分析

Spring MVC是MVC架构模式的一种完美实现,它简化了Java WEB 中基于MVC架构的编程过程,是Spring中的WEB应用模块。

Spring MVC 底层核心架构图及工作流程(先了解,写完项目案例再重点强化)

Spring MVC_第3张图片

 

Spring MVC 中的五大核心组件:

1) DispatcherServlet (前端控制器, 处理请求的入口)

2) HandlerMapping (映射器对象, 用于管理url与对应controller的映射关系)

3) Interceptors(拦截器,实现请求响应的共性处理)

4) Controller (后端控制器, 负责处理请求的控制逻辑)

5) ViewResolver(视图解析器,解析对应的视图关系:前缀+view+后缀)

备注:假如希望了解Spring MVC的详细处理流程可以基于断点调试法进行跟踪。

 

2. Spring MVC 编程基础

2.1. Spring MVC 编程基本步骤

Step01:创建maven web 项目并解决项目中的错误问题

Step02:添加Spring MVC项目核心依赖

Step03:配置Spring MVC项目核心组件

Step04:创建Spring MVC 后端控制器及页面

Step05:部署及测试spring mvc 项目应用。

 

2.2. Spring MVC 编程基础实现(重点)

2.2.1. 创建Maven WEB 项目并添加Spring MVC 依赖

Step01:创建maven web项目

 

1) 项目名 CGB-SPRING-MVC-01

Spring MVC_第4张图片

Spring MVC_第5张图片

 

 

 

2) Web项目打包方式为war方式

Spring MVC_第6张图片

Step02:配置maven web项目

1) 生成web.xml(项目视图)

Spring MVC_第7张图片

2) Web项目的target runtimes为tomcat

Spring MVC_第8张图片

3)Web 项目的编译版本为JDK1.8

Spring MVC_第9张图片

 Step03: 添加Spring MVC项目依赖

 
    
        org.springframework
        spring-webmvc 
        4.3.9.RELEASE 
     

 

2.2.2. 添加Spring MVC配置文件并进行基本配置

在项目的resources的目录中添加核心配置文件(例如spring-configs.xml)并进行基本配置

 
 
     
     
     
     
                             
       
              
         
     

说明:配置文件的名字可以自己指定。

 

2.2.3. 配置Spring MVC前端控制器

打开web.xml,配置DispatcherServlet对象

  
     dispatcherServlet
      org.springframework.web.servlet.DispatcherServlet 
     
        contextConfigLocation
        classpath:spring-configs.xml
     
     1
  
  
     dispatcherServlet
     *.do
  

 前端控制器是spring mvc处理请求的入口,是springmvc的核心,这个控制器一般需要在服务器启动时即初始化

其中

1) load-on-startup 表示启动时则加载此servlet,数字越小优先级越高.

2) init-param 中的参数名不能变(此名字在DispatcherServlet父类中定义)

 

2.2.4. 创建并配置Spring MVC后端控制器

编写Spring MVC后端控制器

@Controller
@RequestMapping("/")
public class HelloController{
    @RequestMapping("doSayHello")
    public ModelAndView doSayHello() {
        ModelAndView mv=new ModelAndView("hello");
        mv.addObject("message", "helloworld");
        return mv;
    }
}

其中:

1)通过@RequestMapping注解定义url到controller具体方法的映射,这个映射信息会被存储,一般是存储到一个HandlerMapping对象中.

2)ModelAndView对象为一个模型与视图对象,内置一个map对象,主要用于封装业务数据和视图名。

3)ModelAndView构造方法中传递的为视图名,addObject方法可以以key/value形式存储数据。

4)ModelAndView 对象返回时会被spring mvc自动存储到请求作用域,在对应的视图页面可以直接从此作用域获取对应的值。

 

2.2.5. 创建JSP页面对象

在项目的WEB-INF/pages文件夹下创建hello.jsp文件,然后设置其内容,例如

${message}

说明:WEB-INF目录下的资源不能允许通过浏览器地址栏直接访问。

 

2.2.6. 部署并运行项目以及请求响应流程分析

将项目部署到tomcat,然后启动运行,在地址栏输入具体url访问对应controller对象。

问题分析:

1) tomcat启动时出现ClassNotFoundException,而这个class又不是我们自己的类,此时要重新maven update,重新发布(右键tomcat 重新publish),多次尝试还是不可以,此时重启eclipse。

2) 404异常,一般表示服务端资源没找到,首先检测访问路径是否正确,然后还可以在项目的部署目录中去查找对应的资源,必须确保资源是存在的,假如资源不存在,说明代码没有正常编译。(很常见)

3) 如何解决这种项目不编译的问题?四大Clean

step01) 停止tomcat将tomcat下的项目移除,并clean你的tomcat服务器(两个clean)

step03) 对项目进行maven clean操作(清除原先编译结构,然后重新编译)

step04) 再次对项目进行clean操作(菜单栏中的project clean)

step05) 重新部署项目,启动tomcat运行

step06) 假如经历了以上几个步骤,还没解决此问题,重启eclipse再试

说明:假如你的eclipse经常出现类似问题,换jdk。

4) 运行项目时尽量不要右键运行选在run as /run on server

Tomcat 启动及对象加载流程分析:

Spring MVC_第10张图片

项目的请求处理流程结构及过程解析:

Spring MVC_第11张图片

Step01:客户端向服务服务端发请求

Step02:服务端对请求信息进行过滤(Filter)

Step03:请求到达前端控制DispatcherServlet

Step04:前端控制器基于url在HandlerMapping中的映射找请求执行链

Step05:执行执行链中的拦截器(Interceptor)方法

Step06:执行执行链中的控制器(Controller)方法

Step07:对象控制层返回的视图进行解析

Step08:向客户端返回一个响应结果。

 

3. Spring MVC 请求处理(day2)

3.1. 请求路径映射

实际项目中我们要借助@RequestMapping注解定义映射路径。其注解应用位置

ü 类定义处: 提供初步的请求映射信息。

ü 方法定义处: 提供进一步的细分映射信息

3.1.1. 普通url映射

@RequestMapping(value={"/doSayHello", "/user/doSayWelcome"}):

多个URL路径可以映射到同一个处理器的功能处理方法。

 

3.1.2. Rest风格url映射

REST即表述性状态传递(英文:Representational State Transfer,简称REST),是一种软件架构编码风格,是基于网络应用进行设计和开发的编码方式。可以降低开发的复杂度,提高程序的可伸缩性。例如:

@RequestMapping("/msg/{xxx}")

请求的URL可以是“/msg/hello”或“/msg/welcome”

@RequestMapping("/msg/{id}/create"):

请求的URL可以是“/users/1/create”。

@RequestMapping("/msg/{mId}/topics/{tId}")

这样也是可以的,请求的URL可以是“/users/10/topics/12”。

 

说明:通过@PathVariable可以提取URI模板模式中的{×××}中的×××变量。

http://localhost:8080/项目名/doUpdate/1.do

 

3.2. 请求方式映射

3.2.1. 请求方式限定

项目中Controller层对象的每个方法默认可以处理任意方式的请求,假如要指定控制层方法只能处理GET或只能处理POST请求,那该如何实现呢?

借助@RequestMapping注解中的method属性指定具体的请求处理方式,例如

@RequestMapping(value=”doSaveObj”,
                method=RequestMethod.POST)
public String doSaveObject(Object obj){….}

知识点扩展:

1)@GetMapping 注解应用(定义的映射只能处理get请求)

2)@PostMapping 注解应用(定义的映射只能处理post请求)

 

3.2.2. 请求方式组合

项目中还可在控制层方法上借助@RequestMapping注解中的method属性指定使用哪几种方式处理请求。

@RequestMapping(value=”doSaveObj”,
                method={RequestMethod.POST,
                RequestMethod.GET})
public String doSaveObject(Object obj){….}

提示:一般浏览器只支持GET或POST方式。

 

3.3. 请求参数映射(重点)

3.3.1. 标准Servlet API(了解)

请求映射方法中可以直接使用ServletAPI 中的对象获取参数数据,例如HttpServletRequest,HttpSession对象等,例如:

@RequestMapping(value="withRequest",method=RequestMethod.GET)
@ResponseBody
public String withRequest(HttpServletRequest request){
    System.out.println(request.getRequestURI());
    return "Obtainer 'foo' query parameter value'"+request.getParameter("gid")+"'";
}

提示:@ResponseBody注解作用:该注解作用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区,使用情况:返回的数据不是Html标签的页面,而是其他数据格式的数据时,(如Json、xml,普通文本等)使用;

 

3.3.2. 直接量对象(重点)

SpringMVC 请求一个控制层资源时,可以在对应方法中直接使用参数变量接收参数数据,但参数变量的类型建议为对象类型

1)使用String类型变量接受请求参数的值:

@RequestMapping(value="withStringParam",method=RequestMethod.GET)
@ResponseBody
public String withStringParam(@RequestParam String foo) {
    return "Obtained 'foo' query parameter value '" + foo + "'";
}

提示:@RequestParam注解用于接收请求参数中名字为foo的参数值,假如请求参数名与方法中的参数名一致,@RequestParam注解可以省略。假如不一致则可以使用@RequestParam注解定义新的参数名直接接收页面数据,然后传递给方法名,还有就是请求参数中包含特殊字符时,需要借助@RequestParam注解对参数进行声明。例如

@RequestMapping(value="withStringParam", method=RequestMethod.GET)
@ResponseBody
public String withStringParam(@RequestParam(value="param-01",required=false) String foo) {
    return "Obtained 'foo' query parameter value '" + foo + "'";
}

提示:required=false表示,参数可以不存在,假如为true(默认),参数不存在时会抛出异常(400异常)。

 

2)使用Date类型变量接受请求日期参数的值:

@RequestMapping(value="withDateParam")
@ResponseBody
public String withDateParam(Date birthday) {
    return "Obtained date parameter value '" + birthday + "'";
}

Spring MVC 默认支持yyyy/MM/dd格式日期转换,假如日期格式不匹配会报400异常

 

3)使用Integer类型的可变参数数组接收请求数据

@RequestMapping(value="withVarParam")
@ResponseBody
public String withVarParam(Integer… ids) {
    return "Obtained ids parameter value '" + ids + "'";
}

3.3.3. Java bean对象(重点)

当请求中多个参数时可以通过在方法中定义多个参数接收参数数据,也可以利用一个javabean对象接收多个参数数据以简化多个参数变量的定义。

@RequestMapping(value="withParamGroup",method=RequestMethod.GET)
@ResponseBody
public String withParamGroup(SysLog entity) {
    return "Obtained javabean parameter group " + entity;
}

 提示:当使用javabean接收请求参数数据时,bean中需要有与参数名对应的set方法

 

3.3.4. 集合Map对象对象(了解)

说明: 通过map接收页面参数时,需要使用@RequestParam注解声明

@RequestMapping("doMap02")
public String withParamGroup (@RequestParam Map map) {
    return "Obtained map parameter group " + map;
}

提示:此时的map不能再作为响应数据的封装对象

 

3.3.5. Rest url数据(重点)

SpringMVC请求资源路径的URL可以通过{XXX}形式指定动态的URL,动态URL中的这个可变参数的值可以直接注入到方法对应的参数中。

@RequestMapping(value="path/{var}",method=RequestMethod.GET)
@ResponseBody
public String withPathVariable(@PathVariable String var) {
    return "Obtained 'var' path variable value '" + var + "'";
}

通过@PathVariable注解指定参数变量var获取请求url中{var}数据

 

3.3.6. 请求头数据(了解)

1)当服务端要获取客户端请求头中数据信息时,可通过@RequestHeader即可将请求头中的属性值绑定到处理方法的入参中,例如获取请求中Accept属性的值,然后传入到对应方法的参数中。

@RequestMapping(value="header", method=RequestMethod.GET)
@ResponseBody
public String withHeader(@RequestHeader String Accept) {
    return "Obtained 'Accept' header '" + Accept + "'";
}

2)假如希望在此方法中直接从cookie取值,可以定义参数时使用@CookieValue对参数进行修饰,参数名一般要与cookie对象中的key相同

@RequestMapping(value="withCookie")
@ResponseBody
public String withCooke(@CookieValue String JSESSIONID) {
    return "Obtained COOKIE Value '" + JSESSIONID + "'";
}

提示:方法中的参数名需要与请求头参数中某个参数名相同,具体请求头相关信息可以在浏览器控制台查看。

3)当应用中要获取请求中所有数据时可以在请求方法中定义一个HttpEntity参数,通过此参数获取请求头及请求体中数据,例如

@RequestMapping(value="entity", method=RequestMethod.POST)
public @ResponseBody String withEntity(HttpEntity entity) {
    return "Posted request body " + entity.getBody() + "headers = " + entity.getHeaders();
}

如上写法:了解

 

4. Spring MVC 响应处理

4.1. 响应数据封装

4.1.1. Servlet API 对象(了解)

将请求数据直接封装到Request 对象

@RequestMapping("doResponse01")
public String doResponse01(HttpServletRequest request) {
    request.setAttribute("data", "hello..");
    return "response";
}

在response.jsp页面可以直接借助${data}方式获取数据。

当方法中直接返回一个页面时,默认执行的是请求转发,假如需要实现重定向,

可以在返回的地址后添加redirect,例如 return "redirect:responseUI.do"; 其中responseUI.do对应一个请求url.

@RequestMapping("doResponse02")
public String doResponse02(HttpServletRequest request) {
    request.setAttribute("data", "hello..");
    return "redirect:responseUI.do";
}

在如上方法中可以重定向到一个responseUI对应的新的URL。

@RequestMapping("responseUI")
public String responseUI() {
    return "response";
}

在新的请求中不能直接获取上一个请求作用域的数据。

 

回顾请求转发与重定向:

Spring MVC_第12张图片

1)请求转发(forward)

Spring MVC_第13张图片

2) 重定向(redirect)

Spring MVC_第14张图片

4.1.2. ModelAndView 对象(重点)

在对服务端响应数据进行封装时,可以直接在方法参数中定义一个ModelAndView类型的参数,借助ModelAndView对象封装响应数据.

@RequestMapping("doModelAndView")
public ModelAndView doModelAndView(ModelAndView mv) {
    //ModelAndView mv=new ModelAndView();
    mv.addObject("data", "model and view");
    mv.setViewName("response");//view
    return mv;
}

提示:ModelAndView 对象由Spring创建,并可以将数据存储到ModelAndView对象的ModalMap类型的属性中(可参考源代码).

 

4.1.3. Model对象(重点)

将响应数据直接封装为model中。

@RequestMapping("doModel")
public String doModel(Model model) {
    model.addAttribute("data", "modal");
    return "response";
}

当我们返回具体view时,系统底层会自动将model对象存储到request作用域

 

4.1.4. Map对象(了解)

将响应数据封装到Map中(我建议假如使用map对数据进行封装,可直接采用model对象)。

@RequestMapping("doMap01")
public String doMap01(Map map) {
    map.put("data", "map..");
    return "response";
}

 

4.2. 响应数据转换JSON(重点)

4.2.1. JSON 应用概述

JSON(JavaScript Object Notation):一种轻量级数据交换格式,通常作为客户端与服务端进行数据交互的一种标准。

企业级Java项目数据传输方式:

Spring MVC_第15张图片

reponse.getWriter().write(jsonStr);

客户端访问服务端时,服务器从数据库取出数据进行封装,然后再将对象转换为json串,通过网络传输到客户端。

 

4.2.2. Spring 集成jackson库

spring 中默认支持jackson应用的,但使用时需要添加jackson依赖,例如


    com.fasterxml.jackson.core
    jackson-databind
    2.8.5

  创建Controller中例如ResponseController,然后在类中添加对应方法。例如:

  将Map对象内容转换为字符串(spring底层会直接访问jackson api将对象转换为字符串)

@RequestMapping("doMap")
@ResponseBody
public Map doMap(){
    Map map=new HashMap<>();
    map.put("id", 100);
    map.put("name", "AAA");
   return map;
}

将JavaBean对象转换为JSON串

@RequestMapping("doUser")
@ResponseBody
public SysLog doLog(){
    SysLog log=new SysLog ();
    log.setId(100);
    log.setUsername("CCC");
    log.setIP("192.168.1.12");
    return log;
  }

将Java List集合转换为JSON串。

@RequestMapping("doList")
@ResponseBody
public List doList(){
    List list=new ArrayList<>();
    SysLog log=new SysLog ();
    log.setId(100);
    log.setUsername("CCC");
    log.setIP("192.168.1.12");
    list.add(log);
    log=new SysLog ();
    log.setId(100);
    log.setUsername("CCC");
    log.setIP("192.168.1.12");
    list.add(log);
    return list;
}

备注:将来controller中数据来自服务端数据。

 

 

你可能感兴趣的:(框架,Spring,MVC)