springAOP注解/Spring事务/SpringMvc

本文详细介绍了SpringMVC的执行流程,包括前端控制器、处理器映射、适配器、视图解析,以及请求与响应的处理方法,涵盖了参数获取、视图跳转、JSON处理等内容。

SpringMvc.png

1.SpringMVC入门

1-1 执行流程 -  图解 -[重点]

image-20220621104734763

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

1-2 组件解析

1.前端控制器DispatcherServlet
用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由
它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。

2.处理器映射器HandlerMapping
HandlerMapping负责根据用户请求找到Handler处理器,springmvc提供了不同的映射器实现不同的映射方式,实现接口方式,注解方式等。

3.处理器适配器HandlerAdapter
通过HandlerAdapter对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。

4.处理器:Handler
它就是我们开发中要编写的具体业务控制器。由 DispatcherServlet 把用户请求转发到 Handler。由Handler 对具体的用户请求进行处理。

5.视图解析器: View Resolver
View Resolver负责将处理结果生成view视图,View Resolver首先根据逻辑视图解析成物理视图名,即具体的页面地址,再生成View视图对象,最后对View进行渲染将处理结果通过页面展示给用户。

6.视图:view
SpringMVC 框架提供了很多的 View 视图类型的支持,包括:jstlView、freemarkerView、pdfView等。最常用的视图就是 jsp。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面

1-3 注解解析

@Controller -  Spring注解

@RequestMapping - 请求映射

   |-用于建立请求 URL 和 处理请求方法之间的对应关系

类上,请求URL 的第一级访问目录。此处不写的话,就相当于应用的根目录
方法上,请求 URL 的第二级访问目录,与类上的使用@ReqquestMapping标注的一级目录一起组成访问虚拟路径

  |-该注解的成员属性

value和path一样 ,别名关系 - 表示请求映射的URL 地址

method 属性  枚举类型RequestMethod  用于限制请求的方式
  |-@RequestMapping(path="/hello",method= RequestMethod.POST)
 使用path或value 及method可以用于唯一标识一个处理器方法

params属性:用于指定限制请求参数的条件
 如果不满足限制条件,则报出HTTP Status 400 – Bad Request
   @RequestMapping(path="/hello",method= RequestMethod.GET,params={"userName"})
   此时表示该请求中必须有参数userName

  |- 由@RequestMapping衍生两个简化注解

 @RequestMapping(path="/hello",method= RequestMethod.GET)

   |-@GetMapping("/hello")
     
   
@RequestMapping(path="/hello",method= RequestMethod.POST)

   |-@PostMapping("/hello")      
     
--------------------------------------------------------------------
@Controller
@RequestMapping("/user")   // 虚拟路径 一级目录 "/user/hello"  restFul风格
public class HelloController {

   @RequestMapping(path="/hello",method= RequestMethod.POST)  // 二级目录
   public String hello(){
       System.out.println("请求到达HelloController.hello()方法....");
       return "../index.jsp";  //request.getRequestDispatcher("/index.jsp").forward(request,response);
   }

   @RequestMapping(path="/hello",method= RequestMethod.GET,params={"userName"})  // 二级目录
   public String hello2(){
       System.out.println("请求到达HelloController.hello2()方法....");
       return "/index.jsp";
   }
}      

1-4 视图解析

在springmvc的jar包中查看属性文件 : DispatcherServlet.properties

该文件中配置了默认的视图解析器,如下:

org.springframework.web.servlet.ViewResolver=
org.springframework.web.servlet.view.InternalResourceViewResolver

在spring-mvc.xml核心配置文件中配置视图解析器

 <!--视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
   <property name="prefix" value="/WEB-INF/views/" />
   <property name="suffix" value=".jsp" />
</bean>

IndexController:

@Controller
public class IndexController {
   @RequestMapping({"/","/index","gotoIndex"})
   public String gotoIndex(){
       return "index";  //返回逻辑视图名,进入视图解析器--解析-->拼接
   }
}

2.SpringMVC请求与响应 --[重点]

2-1 SpringMVC的数据响应

(1) 页面跳转-返回字符串形式

分为两种情形:

a. return "index";   -->进入视图解析器

                                     URL-->        "/WEB-INF/views/index.jsp"   --执行请求转发至该URL

b. return "forward:index"  -->不进入视图解析器

                        |-请求转发给 index 请求

@RequestMapping("/test1")
public String test1(){
   System.out.println("test1()....");
   return "forward:test2"; //转发至下一个url请求方法
   return "forward:/WEB-INF/views/index.jsp"; //不进视图解析器,转发至一个jsp页面
}            

             "redirect:index"  -->不进入视图解析器,发送重定向请求

 @RequestMapping("/test1")
   public String test1(){
       System.out.println("test1()....");
       //return "redirect:/WEB-INF/views/index.jsp";  //不进视图解析器,转发给下一个Controller方法
       return "redirect:/test2"; //重定向
   }

   @RequestMapping("/test2")
   public String test2(){
       System.out.println("test2().....");
       return "index";
   }

(2) 页面跳转-返回ModelAndView-1

ModelAndView --Model模型 view 视图

将数据和视图作为一个对象封装

在Controller方法中直接创建ModelAndView对象封装数据后,再返回

 @RequestMapping("/test3")
public ModelAndView test3(){
   System.out.println("test3()执行了.................");
   ModelAndView mav = new ModelAndView();
   //添加请求作用域
   mav.addObject("name","张三");
   mav.setViewName("index"); //设置逻辑视图名,交给视图解析器
   return mav;
}

(3) 页面跳转-返回ModelAndView-2

将ModelAndView对象直接作为Controller方法的参数

@RequestMapping("/test4")
public ModelAndView test4(ModelAndView mav) {
   System.out.println("test4()执行了.................");
   mav.setViewName("index");
   mav.addObject("name","李四");
   return mav;
}

(4) 页面跳转-使用Model设置作用域

Controller方法的参数,直接使用Model对象来设置请求作用域 属性

@RequestMapping("/test5")
public String test5(Model model) {
   System.out.println("test5()执行了.................");
   model.addAttribute("name","王五");
   return "index";
}

(5) 页面跳转-使用原生HttpServletRequest

在Controller方法的形参上可以直接使用原生的HttpServeltRequest对象,只需声明即可

@RequestMapping("/test6")
public String test6(HttpServletRequest request) {
   System.out.println("test6()执行了.................");
   request.setAttribute("name","Jack");
   return "index";
}

(6) 回写数据-直接回写字符串

类似于Servlet中输出消息:

//ajax请求
response.setContextType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write();
out.flush();
out.close();

SpringMVC应对页面中的ajax请求的处理

将需要回写的字符串直接返回,但此时需要通过@ResponseBody注解告知SpringMVC框架,方法返回的字符串不是跳转是直接在http响应体中返回

@RequestMapping("/test7")
@ResponseBody  //响应主体 -该标注方法返回值,将通过response.getWriter()输出流输出到客户端
public String test7() {
   System.out.println("test7()执行了.................");
   return "index 你好!";
}

[**当我们在方法上面添加@ResponseBody注解之后,SpringMVC不再认为返回值是一个逻辑视图名,而是找相应的消息转换器HttpMessageConverter,我们的消息进行封装和转换,最终输出至页面]

spring-mvc.xml配置消息转换器,输出 支持中文

<mvc:annotation-driven>
   <mvc:message-converters>
        <!--配置字符串消息转换器-->
       <bean class="org.springframework.http.converter.StringHttpMessageConverter">
           <!--<property name="defaultCharset" value="UTF-8" />-->
           <!--设置支持的媒体类型-->
           <property name="supportedMediaTypes">
               <list>
                   <value>text/html;charset=UTF-8</value>
               </list>
           </property>
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

(7) 回写数据-回写json字符串

使用Jackson转换工具

<!--jackson-->
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-core</artifactId>
   <version>2.9.0</version>
</dependency>
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-databind</artifactId>
   <version>2.9.0</version>
</dependency>
<dependency>
   <groupId>com.fasterxml.jackson.core</groupId>
   <artifactId>jackson-annotations</artifactId>
   <version>2.9.0</version>
</dependency>
@RequestMapping("/test8")
@ResponseBody  //响应主体 -该标注方法返回值,将通过response.getWriter()输出流输出到客户端
public String test8() throws JsonProcessingException {
   User user = new User();
   user.setId(1);
   user.setUsername("杰克");
   user.setGender(1);
   user.setBirthday(new Date());
   //Fastjson,Jackson,Gson
   //使用json的转换工具将对象转换成json格式字符串在返回
   ObjectMapper objectMapper = new ObjectMapper();
   //指定日期格式
   DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
   objectMapper.setDateFormat(df);
   String jsonStr =objectMapper.writeValueAsString(user); //将对象转换为json串
   return jsonStr;
}

使用Fastjson

<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>fastjson</artifactId>
   <version>1.2.74</version>
</dependency>
 @RequestMapping("/test8")
@ResponseBody  //响应主体 -该标注方法返回值,将通过response.getWriter()输出流输出到客户端
public String test8() throws JsonProcessingException {
   User user = new User();
   user.setId(1);
   user.setUsername("杰克");
   user.setGender(1);
   user.setBirthday(new Date());

   String jsonStr = JSON.toJSONStringWithDateFormat(user,"yyyy-MM-dd HH:mm:ss");
   return jsonStr;
}

(8) 回写数据-回写对象与集合

通过SpringMVC帮助我们对对象或集合进行json字符串的转换并回写

此时SpringMVC会执行内置的消息转换器

Jackson消息转换器配置:

<mvc:annotation-driven>
   <mvc:message-converters>
       <!--配置Jackson消息转换器-->
       <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
           <!--设置转换时Content-Type-->
           <property name="supportedMediaTypes">
               <list>
                   <value>application/json;charset=UTF-8</value>
               </list>
           </property>
           <!--设置Jackson转换json时使用日期格式-->
           <property name="objectMapper">
               <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                   <property name="dateFormat">
                      <bean class="java.text.SimpleDateFormat">
                       <constructor-arg name="pattern" value="yyyy-MM-dd HH:mm:ss" />
                      </bean>
                   </property>
               </bean>
           </property>
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

Fastjson消息转换器配置:

<mvc:annotation-driven>
   <mvc:message-converters>
       <!--fastjson消息转换器-->
       <bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
           <property name="supportedMediaTypes">
               <list>
                   <value>application/json;charset=UTF-8</value>
               </list>
           </property>
           <!--指定日期格式 WriteDateUseDateFormat - yyyy-MM-dd  HH:mm:ss 推荐使用注解 @JSONField添加到实体类日期字段上 -->
           <!--<property name="features" value="WriteDateUseDateFormat" />-->
       </bean>
   </mvc:message-converters>
</mvc:annotation-driven>

控制器方法:

@RequestMapping("/test9")
@ResponseBody  //响应主体 -该标注方法返回值,将通过response.getWriter()输出流输出到客户端
public User test9() throws JsonProcessingException {
   User user = new User();
   user.setId(1);
   user.setUsername("杰克");
   user.setGender(1);
   user.setBirthday(new Date());
   return user;
}

2-2 SpringMVC的请求

(1) 获得请求参数-基本类型参数

Controller中的业务方法的参数名称要与请求参数的name一致,参数值会自动映射匹配

username=zhangsan&age=12  -- 请求参数 :get:  queryString

                                                                            post: formData

后端:request.getParameter()

@RequestMapping("/test11")
@ResponseBody  //响应主体 -该标注方法返回值,将通过response.getWriter()输出流输出到客户端
public String  test11(String name,Integer age,HttpServletRequest request){
   System.out.println("name="+name);
   System.out.println("age="+age);
   String n = request.getParameter("name");
   Integer a = Integer.parseInt(request.getParameter("age"));
   System.out.println(n+","+a);
   return null;
}

(2) 获得请求参数-POJO类型参数

Controller中的业务方法的POJO参数的属性名与请求参数的name一致,参数值会自动映射匹配

@RequestMapping("/test12")
@ResponseBody
public String  test12(User user){
   System.out.println(user);
   return null;
}

表单请求:

<form action="test12" method="post">
   username:<input type="text" name="username" /><br>
   gender:<input type="text" name="gender" /><br>
   <input type="submit" value="确定">
</form>

如果是post请求方式,需要设置 web.xml:  全局字符集过滤器,解决中文乱码问题

<!--配置全局过滤的filter-->
 <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>
 </filter>
 <filter-mapping>
   <filter-name>CharacterEncodingFilter</filter-name>
   <url-pattern>/*</url-pattern>
 </filter-mapping>

(3) 获得请求参数-数组类型参数

Controller中的业务方法数组名称与请求参数的name一致,参数值会自动映射匹配

<form action="${pageContext.request.contextPath}/quick14" method="get">
   <input type="checkbox" value="1" name="hobby"/>K歌
   <input type="checkbox" value="2" name="hobby"/>打牌
   <input type="checkbox" value="3" name="hobby"/>抽烟
   <input type="submit" value="提交">
</form>
@RequestMapping(value="/quick13")
@ResponseBody
public void save13(String[] hobby) throws IOException {
   System.out.println(Arrays.asList(hobby));
}

SpringMvc.pdf

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值