• SpringMVC入门


    1. SpringMVC入门示例

    1. 导入包

    1. web.xml中配置SpringMVC 核心控制器

      <!-- 配置SpringMVC 核心控制器 -->
      <servlet>
          <servlet-name>springmvc</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>
      </servlet>
      <servlet-mapping>
          <servlet-name>springmvc</servlet-name>  
          <url-pattern>/</url-pattern>
      </servlet-mapping>
      
      
    2. 创建SpringMVC配置文件

      <?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:context="http://www.springframework.org/schema/context" 
      xmlns:aop="http://www.springframework.org/schema/aop" 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/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- bean definitions here -->
      
          <context:component-scan base-package="com.ranger.springMVC.helloSpringMVC"></context:component-scan>
      
      </beans>
      
    3. 编写Controller代码

       @Controller
         public class HelloController {
         	@RequestMapping("/hello")
         	public ModelAndView hello(){
         		System.out.println("HelloController.hello()");
         		ModelAndView mav = new ModelAndView();
         		mav.addObject("msg","hello , SpringMVC");
         		mav.setViewName("/WEB-INF/jsp/hello.jsp");
         		return mav;
         	}
         }
      

    4. 访问测试

      浏览器访问localhost:8080/01-SpringMVC/hello

    2. 配置详解

    1. Dispatcherservlet

      DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据相应的规则分发到目标Controller来处理,是配置spring MVC的第一步。

    1. 以上出现的注解
    • @Controller 负责注册一个bean 到spring 上下文中
    • @RequestMapping 注解为控制器指定可以处理哪些 URL 请求

    3. SpringMVC执行流程图(结构图)

    解释:

    1.用户发送请求至 前端控制器DispatcherServlet。

    2.前端控制器DispatcherServlet收到请求后调用处理器映射器HandlerMapping。

    3.处理器映射器HandlerMapping根据请求的Url找到具体的处理器,生成处理器对象Handler及处理器拦截器HandlerIntercepter(如果有则生成)一并返回给前端控制器DispatcherServlet。

    4.前端控制器DispatcherServlet通过处理器适配器HandlerAdapter调用处理器Controller。

    5.执行处理器(Controller,也叫后端控制器)

    6.处理器Controller执行完后返回ModelAnView。

    7.处理器适配器HandlerAdapter将处理器Controller执行返回的结果ModelAndView返回给前端控制器DispatcherServlet。

    8.前端控制器DispatcherServlet将ModelAnView传给视图解析器ViewResolver。

    9.视图解析器ViewResolver解析后返回具体的视图View。

    10.前端控制器DispatcherServlet对视图View进行渲染视图(即:将模型数据填充至视图中)

    11.前端控制器DispatcherServlet响应用户。

    4. SpringMVC常用注解

    @Controller

      负责注册一个bean 到spring 上下文中
    @RequestMapping

      注解为控制器指定可以处理哪些 URL 请求
    @RequestBody

      该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上 ,再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上

    @ResponseBody

       该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区

    @ModelAttribute    

      在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法

      在方法的入参前使用 @ModelAttribute 注解:可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数 –绑定到对象中,再传入入参将方法入参对象添加到模型中

    @RequestParam 

      在处理方法入参处使用 @RequestParam 可以把请求参 数传递给请求方法

    @PathVariable RESTful风格使用

      绑定 URL 占位符到入参
    @ExceptionHandler

      注解到方法上,出现异常时会执行该方法
    @ControllerAdvice

      使一个Contoller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常

    5. SSM 整合配置

    整合思路:

    • DAO层:
      • SqlMapConfig.xml (空文件即可,不过需要包含头文件)
      • applicationContext-dao.xml
        • 数据库连接池
        • SqlSessionFactory对象
        • 配置Mapper文件扫描器
    • Service层
      • applicationContext-service.xml 配置包扫描 ,扫描@Service
      • applicationContex-tx.xml 配置事务相关
    • Controller层
      • springmvc.xml
        • 配置包扫描 扫描@Controller类
        • 配置注解驱动
        • 配置视图解析器
    • web.xml
      • 配置Spring容器监听器
      • 配置前端控制器

    6. SpringMVC默认支持的参数

    • HttpServletRequest
    • HttpServletResponse
    • HttpSession
    • Model

    7. 简单参数传递

    @RequestMapping("/editItem")
    public ModeAndView editItem(Integer id){     // 会自动将链接中的属性id传到这里的id (参数名要一致)
        itemService.getItemById(id);
        // .......
    }
    
    // 如果参数名不一致
    @RequestMapping("/editItem")
    public ModeAndView editItem(@RequestParam("id")Integer ids){     // 会自动将链接中的属性id传到这里的ids
        itemService.getItemById(ids);
        // .......
    }
    
    
    ReqeustParam注解中的参数
    @ReqeustParam(value="id",required=true,defaultValue="1")
    
    
    

    8. POJO参数绑定

    表单提交的属性和POJO类的属性一致

     绑定很简单,对于基本类型,要求页面中input标签的name属性值和controller的pojo形参中的属性名称一致,即可将页面中数据绑定到pojo。也就是说前台页面传进来的name要和要封装的pojo属性名一模一样,然后就可以将该pojo作为形参放到controller的方法中

    9. 包装POJO参数绑定

    包装类型pojo指的是pojo中有另一个也是pojo的属性,即pojo套pojo,为什么会设计这种pojo呢?在前面的博文中我也有提到,这种组合的设计方法对于后期程序的扩展很有用,比如复杂的查询条件就需要包装到这种包装类型中

    使用item.name

    10. 高级参数绑定

    数组参数的传递

    数组的绑定指的是前台传来多个同一类型的数据,我们在controller中使用数组形参来接收前台传来的数据。还是以案例来驱动这部分内容,比如现在我们要批量删除商品,那么我们需要勾选好几个商品,这些商品都有id号,在controller中,我们需要将这些id号全部获取并放到一个数组中,然后再根据数组中的id号挨个删除数据库中对应的项。

    例如批量删除商品,需要传入删除的id

    List类型的绑定

     通常在需要批量提交数据时,将提交的数据绑定到list<pojo>中,比如:成绩录入(录入多门课成绩,批量提交),在这里我们假设有需求:批量商品修改,在页面输入多个商品信息,将多个商品信息提交到controller方法中,即一次性更新多个商品信息。
      所以思路是在扩展类ItemsQueryVo中新添加一个List<ItemsCustom>,然后将不同商品的信息都存到这个List中

    前台是通过类似于list[i].name这种形式来传递参数的。list[i]表示第i个ItemsCustom,然后 list[i].属性 表示第i个ItemsCustom中对应的属性。

    Map类型的绑定

    Map类型和List差不多

    Map的参数绑定传来的是Map中的key,然后value会自动绑定到Map中的那个对象的属性中。在controller中的方法里,形参就直接使用QueryVo接收即可

    自定义类型的封装

    对于字符串向日期类型的转换,需要自定义转换器


    然后在SpringMVC 中配置自定义的转换器

    11. RequestMapping 注解详解

    1. 路径映射可以是数组

      @RequestMapping(value={"itemList",itemLIst1})

    2. @RequestMapping可以加在类头部,用于目录分级管理

    3. 限定请求方法

      @RequestMapping(method=RequestMethos.POST)

      可以是数组

    12. 请求乱码问题

    • GET 方式

      修改tomcat服务器配置文件server.xml

      添加connector标签属性urlEncoding="utf-8"

    • POST 方式

    13. Controller的方法返回值

    ModeAndView 类型的返回值
    • 设置Mode中的属性
    • 设置视图
    void 类型的返回值
    • request
    • response
    String类型的返回值
    • 返回视图名称
    • redirect
      • return “redirect:/itemList”
      • 参数传递问题
        • 通过URL模板以路径变量或查询参数形式传递数据
        • 通过flash属性传递数据(RedirectAttributes)
    • forward
      • return "forward:/itemList"
      • 参数传递 request.setAttribute()

    14. SpringMVC 的异常处理

    代码中处理

    麻烦

    统一(全局)处理
    1. 编写处理程序

      /**
       * 全局异常处理器
       * 
       */
      public class CustomerException implements HandlerExceptionResolver {
      
          @Override
          public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object hanlder,
                  Exception e) {
              //记录日志
              e.printStackTrace();
              //错误消息 
              String msg = "很抱歉,系统发生异常了,请联系管理员";
      
              //响应用户错误提示
              ModelAndView mav = new ModelAndView();
              //返回错误消息
              mav.addObject("msg", msg);
              //响应错误提示页面
              mav.setViewName("msg");
              return mav;
          }
      }
      
      
    2. 配置处理器

      application-mvc.xml中配置一个bean

      <bean class="CLASSPATH"  ></bean>
      
    3. 为了更加友好的显示,处理不同类型异常,可以自定义异常类,然后在异常全局自定义处理类的方法中怕暖异常类型,然后给出不同的提示

    15. 图片上传

    1. 配置服务器虚拟路径

    1. 引入jar包

    1. SpringMVC 配置文件中配置多媒体解析器

      <!-- 配置多媒体处理器 -->
      <!-- 注意:这里id必须填写:multipartResolver -->
      <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
          <!-- 最大上传文件大小 -->
          <property name="maxUploadSize" value="8388608" />
      </bean>
      
      
    2. 注意文件上传表单中的enctype='multipart/form-data' method='POST'

    3. 编写文件上传代码

      //图片上传用MultipartFile接收文件
      @RequestMapping(value = "updateItem", method = { RequestMethod.POST, RequestMethod.GET })
      public String updateItem(Item item, Model model, MultipartFile picFile) throws Exception {
      
          // 图片新名字
          String name = UUID.randomUUID().toString();
          // 图片原名字
          String oldName = picFile.getOriginalFilename();
          // 后缀名
          String exeName = oldName.substring(oldName.lastIndexOf("."));
      
          File pic = new File("D:\WebWork\" + name + exeName);
          // 保存图片到本地磁盘
          picFile.transferTo(pic); 
          // 更新商品图片信息
          item.setPic(name + exeName);
      
          itemServices.update(item);
          model.addAttribute("item", item);
          model.addAttribute("msg", "修改商品成功");
          return "itemEdit";
      }
      
      

    16. Json数据交互

    mvc:annotation-driven/ 提供了json交互

    1. 导入jar包

    1. 编码

      /**
      	 * json数据交互演示
      	 * 
      	 * @param item2
      	 * @return
      	 */
      	@RequestMapping("getItem")
      	//@ResponseBody把pojo转成json串响应用户
      	@ResponseBody
      	//@RequestBody用于接收用户传入json串转成pojo
      	public Item getItem(@RequestBody Item item2) {
      
      		System.out.println("接收到的json商品数据为:" + item2);
      
      		Item item = itemServices.getItemById(3);
      		return item;
      	}
      
      
    2. 测试

    17. RESTful风格

    代码

    /**
    	 * RESTful风格演示
    	 * 
    	 * @param ids
    	 * @param model
    	 * @return
    	 */
    //RESTful风格url上的参数通过{}占位符绑定
    //占位符参数名与方法参数名不一致时,通过@PathVariable绑定
    @RequestMapping("/item/{id}")
    public String testRest(@PathVariable("id") Integer ids, Model model) {
        Item item = itemServices.getItemById(ids);
        model.addAttribute("item", item);
        return "itemEdit";
    }
    
    

    18. 拦截器

    1. 定义拦截器

      public class MyInterceptor1 implements HandlerInterceptor {
      
      	//在Controller方法执行后被执行
      	//处理异常、记录日志
      	@Override
      	public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
      			throws Exception {
      		System.out.println("MyInterceptor1.afterCompletion.....");
      	}
      
      	//在Controller方法执行后,返回ModelAndView之前被执行
      	//设置或者清理页面共用参数等等
      	@Override
      	public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
      			throws Exception {
      		System.out.println("MyInterceptor1.postHandle.....");
      	}
      
      	//在Controller方法执行前被执行
      	//登录拦截、权限认证等等
      	@Override
      	public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {
      		
      		System.out.println("MyInterceptor1.preHandle.....");
      		
      		//返回true放行,false拦截
      		return true;
      	}
      
      }
      
      
    2. SpringMVC中配置拦截器

      <!-- 拦截器定义 -->
      	<mvc:interceptors>
      		<!-- 定义一个拦截器 -->
      		<mvc:interceptor>
      			<!-- path配置</**>拦截所有请求,包括二级以上目录,</*>拦截所有请求,不包括二级以上目录 -->
      			<mvc:mapping path="/**"/>
      			<bean class="com.itheima.springmvc.interceptor.MyInterceptor1" />
      		</mvc:interceptor>
      		
      		<!-- 定义一个拦截器 -->
      		<mvc:interceptor>
      			<!-- path配置</**>拦截所有请求,包括二级以上目录,</*>拦截所有请求,不包括二级以上目录 -->
      			<mvc:mapping path="/**"/>
      			<bean class="com.itheima.springmvc.interceptor.MyInterceptor2" />
      		</mvc:interceptor>
      	</mvc:interceptors>
      
      
      1. 顺序

        • preHandler 按照配置顺序调用
        • postHandler 按照配置顺序逆序调用
        • afterCompletion 按照配置顺序逆序调用
      2. 案例

        • 登录权限验证

          判断是否登录,登录则放行

          未登录则跳转到登录页面

  • 相关阅读:
    我为什么支持从中学课本中撤下鲁迅的文章?
    【老孙随笔】技术不行别人就不服你,怎么办?
    【老孙随笔】求职,不要无的放矢
    读者来信(1)——项目经理,不要迷信制度!
    欣闻鲁迅文章下架
    知道力读书会,欢迎大家参加
    【老孙随笔】是谁杀死了QQ?
    技术,项目经理的命?——项目经理的误区(3)
    可以不封神,但是不能不修炼——亚特兰蒂斯之神特斯拉的启示
    分布式开发2WCF如何正确调用LINQTO SQL
  • 原文地址:https://www.cnblogs.com/watertreestar/p/11740783.html
Copyright © 2020-2023  润新知