SpringMVC基础(1):SpringMVC概述

​​​​

目录

0、写在前面

SpringMVC1

什么是SpringMVC?

SpringMVC入门

补充:请求参数的绑定(非常重要)

常用注解?

SpringMVC第二篇

响应数据和结果视图

细节:Tomcat默认不能进行delete和put,需要修改 readonly 属性;具体教程

SpringMVC的异常处理

SpringMVC中的拦截器

第三篇 重头戏:SSM整合


0、写在前面

原文:SpringMVC【入门】篇_Mr.东方老赢的博客-CSDN博客

SpringMVC1

  • 什么是SpringMVC?

    • 概念

      Spring MVC属于SpringFrameWork的后续产品,已经融合在Spring Web Flow里面。Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的 MVC 架构,从而在使用Spring进行WEB开发时,可以选择使用Spring的Spring MVC框架或集成其他MVC开发框架,如Struts1(现在一般不用),Struts 2(一般老项目使用)等。
      • Model(模型):数据模型,提供要展示的数据,因此包含数据和行为,可以认为是领域模型或 JavaBean 组件(包含数据和行为),不过现在一般都分离开来:Value Object(数据) 和 服务层(行为)。也就是模型提供了模型数据查询和模型数据的状态更新等功能,包括数据和业务。

      • View(视图):负责进行模型的展示,一般就是我们见到的用户界面,客户想看到的东西。

      • Controller(控制器):接收用户请求,委托给模型进行处理(状态改变),处理完毕后把返回的模型数据返回给视图,由视图负责展示。

    • 三层框架

    • SpringMVC运行原理

    在这里插入图片描述

  • SpringMVC入门

    • 搭建开发环境
      • Tomcat下载及安装教程
      • 第一步,创建工程:正常创建maven工程,选择webapp(注意是maven下的)
        在这里插入图片描述
      • 第二步:创建之后再main下创建javaresources两个文件夹(我这里是直接创建文件夹类型就给定义好了,如果创建出来是普通的文件夹,可以右键文件夹选择Mark Directory as然后选择相应类型:java选择Sources Rootresources选择Resources Root

        在这里插入图片描述
      • 第三步:在pom.xml中添加依赖
        在这里插入图片描述
      • 第四步:配置web.xml文件(前端配置器)
        在这里插入图片描述
      • 第五步:在resources文件夹下创建配置文件
        在这里插入图片描述
    • 编写入门程序
      • 首先在index.jsp文件中添加一个超链接标签用于跳转
        在这里插入图片描述
      • 然后新建一个controller类:方法返回值可做跳转页面的文件名
        在这里插入图片描述
      • springmvc.xml主配置文件中进行配置
        在这里插入图片描述
        WEB-INF下创建文件夹pages,并在pages中创建跳转页面success.jsp
        在这里插入图片描述
      • 配置web.xml
        在这里插入图片描述
      • 开启tomcat运行测试,运行结果
        在这里插入图片描述
        运行原理解析
        在这里插入图片描述





    补充:请求参数的绑定(非常重要)


1. 请求参数邦定入门

/*param.jsp*/

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    <a href="param/testParam?username=user&password=123456">请求参数绑定</a>
</body>
</html>
package it.mvc.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * @Author: 东方老赢
 * @Date: 2020/4/19 14:18
 */
@Controller
@RequestMapping("param")
public class ParamController {

    @RequestMapping("testParam")
    public String testParam(String username,String password){
        System.out.println("执行了");
        System.out.println(username);
        System.out.println(password);
        return "success";
    }
}

运行结果
在这里插入图片描述
在这里插入图片描述


2. 请求参数绑定实体类型

//1.创建user实体类

package it.mvc.domain;

import java.io.Serializable;

/**
 * @Author: 东方老赢
 * @Date: 2020/4/19 14:42
 */
public class User implements Serializable {
    private String uname;
    private Integer age;

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "uname='" + uname + '\'' +
                ", age=" + age +
                '}';
    }
}
//2.创建Account实体类,并引用user实体类

package it.mvc.domain;

import java.io.Serializable;

/**
 * @Author: 东方老赢
 * @Date: 2020/4/19 14:32
 */
public class Account implements Serializable {
    private String username;
    private String password;

//    实体类中有引用实体类
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "Account{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", user=" + user +
                '}';
    }
}
//在ParamController中创建方法,接受参数为实体类

 @RequestMapping("saveParam")
    public String saveParam(Account account){
        System.out.println("执行了");
        System.out.println(account);
        return "success";
    }
<%-- 使用表单提交的方式提交信息 --%>

<body>
<form action="param/saveParam" method="post">
    账户<input type="text" name="username"/><br/>
    密码<input type="text" name="password"/><br/>
<%--    实体类中有引用实体类的传参--%>
    姓名<input type="text" name="user.uname"/></br>
    年龄<input type="text" name="user.age"/></br>
    <input type="submit" value="提交">
</form>
</body>
  • 测试结果:

在这里插入图片描述
在这里如果你输入中文就会发现控制台输出乱码,这时我们就要配置解决中文乱码的过滤器
在主配置文件web.xml中加入下列代码(==注意!!==要写在前端控制器之前,否则排列顺序不对,web-app标签会标红)

<!--配置解决中文乱码的过滤器-->
  <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. 请求参数绑定集合类型

与上述步骤基本一致,这里只展示不同部分

//实体类中引用集合,添加get、set和toString方法

 private List<User> list;
    private Map<String,User> map;

    public List<User> getList() {
        return list;
    }

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

    public Map<String, User> getMap() {
        return map;
    }

    public void setMap(Map<String, User> map) {
        this.map = map;
    }
<form action="param/saveParam" method="post">
    账户<input type="text" name="username"/><br/>
    密码<input type="text" name="password"/><br/>
<%--    实体类中有集合传参--%>
    姓名<input type="text" name="list[0].uname"/></br>
    年龄<input type="text" name="list[0].age"/></br>
    姓名<input type="text" name="map['one'].uname"/></br>
    年龄<input type="text" name="map['one'].age"/></br>
    <input type="submit" value="提交">
</form>
  • 运行结果

在这里插入图片描述



4.自定义类型转换器代码编写

问题:网页传参都是String格式,而SpringMVC在传参的过程中自动进行了类型转换,但是也有个别案例。
	如:默认可转换的日期格式为 yyyy/MM/dd,如果输入日期格式为 yyyy-MM-dd,则会报错

在这里插入图片描述
代码编写:(SpringMVC为我们提供了一个接口,用于我们自己编写转换代码)
在这里插入图片描述
1.在User实体类中加入Date属性,并添加get、set方法(此处就不展示了)

//2.创建字符串转化类

package it.mvc.utiles;

import org.springframework.core.convert.converter.Converter;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author: 东方老赢
 * @Date: 2020/4/19 17:19
 *
 * 将字符串转换为指定格式日期
 */

public class StringToDateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String s) {
        if (s == null){
            throw new RuntimeException("没有数据!!!");
        }
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        try {
            return df.parse(s);
        } catch (ParseException e) {
            throw new RuntimeException("数据类型转换出现错误!!!");
        }
    }
}

<!--3.在主配置文件springmvc.xml文件中配置-->

<!--    配置自定义类型转换器-->
    <bean id="conversionServiceFactoryBean" class="org.springframework.context.support.ConversionServiceFactoryBean">
        <property name="converters">
            <set>
<!--                配置路径-->
                <bean class="it.mvc.utiles.StringToDateConverter"></bean>
            </set>
        </property>
    </bean>

<!--    开启springmvc框架注解支持  手动开启类型转换-->
    <mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
//4.添加转换方法

 @RequestMapping("StringToDate")
    public String StringToDate(User account){
        System.out.println("执行了");
        System.out.println(account);
        return "success";
    }
//5.表单提交测试
<form action="param/StringToDate" method="post">
    账户<input type="text" name="uname"/><br/>
    密码<input type="text" name="age"/><br/>
   生日 <input type="text" name="birthday"><br/>
    <input type="submit" value="提交">
</form>
  • 运行通过说明你成功啦!


细节:怎么通过SpringMVC获取Servlet原生API

<%--1.编写超链接--%>
    <a href="param/getServlet">获取servlet原生API</a>
 /**
     * 2.获取Servlet原生API
     * @param request
     * @param response
     * @return
     */
    @RequestMapping("getServlet")
    public String getServlet(HttpServletRequest request, HttpServletResponse response){
        System.out.println("执行了");
        System.out.println(request);

        HttpSession session = request.getSession();
        System.out.println(session);

        ServletContext servletContext = session.getServletContext();
        System.out.println(servletContext);

        System.out.println(response);
        return "success";
    }
  • 运行结果:
    在这里插入图片描述
  • 常用注解?

  • @RequestParam()

作用:把请求中指定名称的参数给控制器形参赋值(即网页传参名称与方法中参数名不一致时可用)
属性:

  • value:请求参数中的名称
  • required:请求参数中是否必须提供此参数。默认值为true。表示必须提供,不提供会出错
<a href="anno/testRequestParam?name=haha">testRequestParam</a>
  @RequestMapping("/testRequestParam")
    public String testRequestParam(String username){
        System.out.println(username);
        return "success";
    }

运行结果:
在这里插入图片描述
细节:当添加了注解之后,网页传参的参数名称必须与注解中的一致,否则会报错



  • @RequestBody()

作用:用于获取请求体内容。直接使用得到的是 key=value&key=value结构的数据(get方式不适用)
属性:

  • required:是否必须有请求体,默认为true。 当取值为true时,get请求方式会报错。如果取值为false,get请求得到的是null
<form action="anno/testRequestBody" method="post">
    用户:<input type="text" name="username"><br/>
    密码:<input type="text" name="password"><br/>
    <input type="submit" value="提交">
</form>
 @RequestMapping("/testRequestBody")
    public String testRequestBody(@RequestBody String body){
        System.out.println(body);
        return "success";
    }

运行结果:
在这里插入图片描述

  • @PathVariable()

作用:用于绑定url中的占位符。例如:请求url中/delete/{id},这个{id}就是占位符。(url支持占位符是spring3.0之后加入的,是springmvc支持restful风格url的一个重要标志)
属性:

  • value:用于指定url中占位符的位置
  • required:是否必须提供占位符
<a href="anno/testPathVariable/10">testPathVariable</a>
 @RequestMapping("/testPathVariable/{sid}")
    public String testPathVariable(@PathVariable(name = "sid") String id){
        System.out.println(id);
        return "success";
    }

运行结果:
在这里插入图片描述

  • HiddenHttpMethodFilter过滤器

  • 作用:由于浏览器form表单只支持get与post请求,而default、put等method并不支持,spring3.0添加了一个过滤器,可以将浏览器请求改为指定的请求方式,发送给我们的控制器方法,使得支持get、post、put与delete请求
  • 使用方法:
    • 第一步:在web.xml中设置过滤器
    • 第二步:请求方式必须使用post请求
    • 第三步:按照要求提供_method请求参数,该参数的取值就是我们需要的请求方式
  • @RequestHeader()(用处不大)

作用:用于获取请求消息头
属性:

  • value:提供消息头名称
  • required:是否必须有此消息头

注:使其开发中一般不用

<a href="anno/testRequestHeader">testRequestHeader</a>
 @RequestMapping("/testRequestHeader")
    public String testRequestHeader(@RequestHeader(value = "Accept") String header){
        System.out.println(header);
        return "success";
    }

运行结果
在这里插入图片描述

  • @CookieValue()(用的也较少)

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

  • value:指定cookie的名称
  • required:是否必须有cookie
<a href="anno/testCookieValue">testCookieValue</a>
 @RequestMapping("/testCookieValue")
    public String testCookieValue(@CookieValue(value = "JSESSIONID") String cookie){
        System.out.println(cookie);
        return "success";
    }
  • 运行结果:

在这里插入图片描述

  • @ModelAttribute()‘’

作用:该注解是springmvc4.3版本之后加入的,他可以用于修饰方法和参数

  • 出现在方法上:表示当前方法会在控制器执行之前执行。它可以修饰没有返回值的方法,也可以修饰有具体返回值的方法
  • 出现在参数上,获取指定的数据给参数赋值

属性:

  • value:用于获取数据的key。key可以是POJO的属性名称,也可以是map结构的key

应用场景:

  • 当表单提交数据不是完整的实体类数据时,保证没有提交数据的字段使用数据库对象原来的数据
    例如:我们在编辑一个用户时,用户有一个创建信息的字段,该字段的值是不允许被修改的。在提交表单数据是肯定没有此字段的内容,一旦更新会把该字段内容置为null,此时就可以使用此注解解决问题
<form action="anno/testModelAttribute" method="post">
    用户:<input type="text" name="uname"><br/>
    密码:<input type="text" name="age"><br/>
    <input type="submit" value="提交">
</form>
  @RequestMapping("/testModelAttribute")
        public String testModelAttribute(User user){
            System.out.println(user);
            return "success";
        }

    /**
     * 该方法会先执行,与表单提交重复的内容会被表单覆盖,表单没有的内容原封不动的传上去
     * @param uname
     * @return
     */
    @ModelAttribute
        public User showUser(String uname){
            System.out.println("showUser执行了");
            //通过用户名查询数据库(模拟)
            User user = new User();
            user.setUname(uname);
            user.setAge(20);
            user.setBirthday(new Date());
            return user;
        }
 @RequestMapping("/testModelAttribute")
        public String testModelAttribute(@ModelAttribute("abc") User user){
            System.out.println(user);
            return "success";
        }

    /**
     * 未带参数的方法需要添加到 map中
     * @param uname
     * @param map
     */
    @ModelAttribute
    public void showUser(String uname, Map<String,User> map){
        System.out.println("showUser执行了");
        //通过用户名查询数据库(模拟)
        User user = new User();
        user.setUname(uname);
        user.setAge(20);
        user.setBirthday(new Date());
        map.put("abc",user);
    }

运行效果:表单只提交了两项,覆盖掉了showUser()方法中的相同参数的两项,方法中未重复的日期参数则会原封不动的传上去
在这里插入图片描述
在这里插入图片描述

  • @SessionAttributes()

作用:用于多次执行控制器方法间的参数共享
属性:

  • value:用于指定存入的属性名称
  • type:用于指定存入的数据类型
    /**
     * 存入session
     * @param model
     * @return
     */
    @RequestMapping("/testSessionAttributes")
    public String testSessionAttributes(Model model){
        model.addAttribute("msg","东方老赢");
        return "success";
    }

    /**
     * 获取session
     * @return
     */
    @RequestMapping("/getSessionAttributes")
    public String getSessionAttributes(ModelMap modelmap){
        String msg = (String) modelmap.get("msg");
        System.out.println(msg);
        return "success";
    }

    /**
     * 删除session
     * @return
     */
    @RequestMapping("/delSessionAttributes")
    public String delSessionAttributes(SessionStatus status){
        status.setComplete();
        return "success";
    }
<a href="anno/testSessionAttributes">testSessionAttributes</a>
<a href="anno/getSessionAttributes">getSessionAttributes</a>
<a href="anno/delSessionAttributes">delSessionAttributes</a>

运行:
在这里插入图片描述

SpringMVC第二篇

  • 响应数据和结果视图

        /**
         * 使用Model
         * @param model
         * @return
         */
        @RequestMapping("/testModel")
        public String testModel(Model model){
            User user = new User();
            user.setUsername("东方老赢");
            user.setPassword("123456");
            user.setAge(20);
            model.addAttribute(user);
            return "success";
        }
    
        /**
         * 使用jsp
         */
        @RequestMapping("/testVoid")
        public void testVoid(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            //编写请求转发的程序
    //        request.getRequestDispatcher("/WEB-INF/pages/success.jsp").forward(request,response);
    
            //重定向(重定向无法请求/WEB-INF/pages中的jsp文件)
    //        response.sendRedirect(request.getContextPath()+"/response.jsp");
    
            //设置中文乱码
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
    
            //直接会进行响应
            response.getWriter().print("东方老赢");
            return;
        }
    
    
        /**
         * 使用ModelAndView
         */
        @RequestMapping("/testModelAndView")
        public ModelAndView testModelAndView(){
            ModelAndView mv = new ModelAndView();
    
            User user = new User();
            user.setUsername("东方老赢");
            user.setPassword("123456");
            user.setAge(20);
    
            mv.addObject("user",user);
            mv.setViewName("success");
            return mv;
        }
    
        @RequestMapping("/testForwardOrRedirect")
        public String testForwardOrRedirect(){
            //请求的转发
    //        return "forward:/WEB-INF/pages/success.jsp";
            //重定向
            return "redirect:/response.jsp";
        }
    
    • 返回值分类

    • SpringMVC框架提供的转发和重定向
    • ResponseBody响应json数据
    1. 在webapp下创建js文件夹,导入jquery.min.js
      在这里插入图片描述

    2. 导入json需要的jar包

      <!--    json字符串与Javabean对象相互转换过程中,需要用到jackson的jar包-->
          <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-core</artifactId>
            <version>2.9.0</version>
          </dependency>
          <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
          </dependency>
      
    3. 编写JavaScript代码

    4. 编写controller代码,模拟服务器响应

      /**
           * @RequestBody:服务器接收到的json格式的数据解析成实体类型
           * @ResponseBody:服务器响应时将返回的数据解析成json格式
           *
           * @param user
           * @return
           */
          @RequestMapping("/testAjax")
          public @ResponseBody User testAjax(@RequestBody User user){
              //客户端发送ajax请求,传的是ajax字符串,后端把json字符串封装到user对象中
              System.out.println(user);
              //做响应,模拟查询数据库
              user.setUsername("东方老赢");
              user.setPassword("654321");
              user.setAge(25);
              return user;
          }
      
      • SpringMVC实现文件上传
    • 文件上传的必要前提:

    1. form表单的enctype取值必须是:multipart/form-data(enctype:是表单请求正文的类型)
    2. method的属性取值必须是Post
    3. 提供一个文件选择域 <input type=“ file ”/>


    • 文件上传的原理分析:

      当form表单的enctype取值不是默认值之后,request.getParameter( ) 将失效
      enctype = “application/x-www-from-urlencoded”(即默认值)时,form表单的正文内容是:

      • key = value&key = value&key = value

      当form表单的enctype取值为 multipart/form-data 时,请求正文的内容就变成

      • 每一部分都是MIME类型描述的正文
        ================================7de1a433602ac            分界符
        Content- Disposition:form-data;name=“userName”                          协议头
        aaaa                                                                                                  协议正文
        ================================7de1a433602ac            分界符
        Content- Disposition : form-data ; name = “file”;filename = “C:\xxx\xxx\b.txt”
        Content-Type:text/plain                                                          协议类型(MIME类型)
        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
        ================================7de1a433602ac           

    借助第三方组件实现文件上传: commons-fileupload-x.x.x.jar、commons-io-x.x.jar

     <dependency>
          <groupId>commons-fileupload</groupId>
          <artifactId>commons-fileupload</artifactId>
          <version>1.3.1</version>
        </dependency>
        <dependency>
          <groupId>commons-io</groupId>
          <artifactId>commons-io</artifactId>
          <version>2.4</version>
        </dependency>
    
     <form action="user/fileupload1" method="post" enctype="multipart/form-data">
            浏览文件<input type="file" name="upload"/><br/>
            <input type="submit" value="上传"/>
        </form>
    
      @RequestMapping("/fileupload1")
        public String fileupload1(HttpServletRequest request) throws Exception {
            System.out.println("成功执行 传统文件上传");
    
            //使用fileupload组件完成文件上传
            //上传的位置
            String path = request.getSession().getServletContext().getRealPath("/uploads/");
            System.out.println(path);
            //判断该路径是否存在
            File file = new File(path);
            //不存在则创建该文件夹(在工程target文件夹下)
            if (!file.exists()){
                file.mkdirs();
            }
    
            //解析request对象,获取上传文件项
            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            //解析requesth得到一个list集合
            List<FileItem> items = upload.parseRequest(request);
            System.out.println(items);
            //遍历
            for (FileItem item : items) {
                //进行判断,当前item对象是否是上传文件项
                if (item.isFormField()){
                    //为true,书名普通表单项
                    System.out.println("普通表单项");
                }else {
                    //为false说明上传文件项
                    //获取上传文件的名称
                    System.out.println("上传文件项");
                    String name = item.getName();
                    System.out.println(name);
                    //完成文件上传
                    item.write(new File(path,name));
                    //删除临时文件
                    item.delete();
                }
            }
            return "success";
        }
    

    在这里插入图片描述
    在这里插入图片描述

文件上传的回顾



  • SpringMVC传统方式文件上传



  • SpringMVC跨服务器方式文件上传



  • 步骤:

  1. 添加jar包

    <!--    允许跨服务器上传文件-->
        <dependency>
          <groupId>com.sun.jersey</groupId>
          <artifactId>jersey-core</artifactId>
          <version>1.18.1</version>
        </dependency>
        <dependency>
          <groupId>com.sun.jersey</groupId>
          <artifactId>jersey-client</artifactId>
          <version>1.18.1</version>
        </dependency>
      </dependencies>
    
  2. 添加新表单

  3. 创建新工程模拟图片服务器,并部署tomcat测试是否成功
    在这里插入图片描述
    在这里插入图片描述

  4. Controller代码

     @RequestMapping("/fileupload3")
        public String fileupload3(MultipartFile upload) throws Exception {
            System.out.println("成功执行 Springmvc跨服务器文件上传");
    
    
            String path = "http://localhost:9090/fileupload_war/uploads/";
            //获取上传文件的名称
            String name = upload.getOriginalFilename();
            //创建客户端的对象
            Client client = Client.create();
            //和图片服务器进行连接
            WebResource webResource = client.resource(path+name);
            //完成文件上传
            webResource.put(upload.getBytes());
    
            return "success";
        }
    
  5. 运行测试即可





细节:Tomcat默认不能进行delete和put,需要修改 readonly 属性;具体教程





  • SpringMVC的异常处理



    • 异常处理思路

    Controller调用service,service调用dao,异常都是向上抛出的,最终有DispatcherServlet找异常处理器进行一场的处理
    在这里插入图片描述



    • SpringMVC的异常处理

    1. 编写自定义异常类(做提示信息)

      package com.mvc.exception;
      
      /**
       * @Author: 东方老赢
       * @Date: 2020/4/23 11:02
       */
      public class SysException extends Exception {
      
          //存储提示信息
          private String message;
      
          @Override
          public String getMessage() {
              return message;
          }
      
          public void setMessage(String message) {
              this.message = message;
          }
      
          public SysException(String message) {
              this.message = message;
          }
      }
      
    2. 编写异常处理器

    3. 配置异常处理器

      <!--    配置异常处理器-->
          <bean id="sysExceptionResolver" class="com.mvc.exception.SysExceptionResolver"></bean>
      
      • 1
      • 2




  • SpringMVC中的拦截器



    • 拦截器的作用

    SpringMVX中的拦截器类似于Servlet中的过滤器Filter,用于对处理器进行预处理和后处理
    谈到拦截器,还要提一个词——拦截器链(Interceptor Chain)。拦截器链就是将拦截器按一定顺序联结成一条链。在访问被拦截的方法和字段之时,拦截器链中的拦截器就会按其之前定义的顺序被调用
    拦截器预过滤器的区别:

    • 过滤器是servlet规范中的一部分,任何java web工程都可以用
    • 拦截器是SpringMVC框架自己的,只有使用了SpringMVC框架的工程才能使用
    • 过滤器在url-patten 中配置 /* 之后,可以对所有要访问的资源进行拦截。
    • 拦截器只会拦截访问的控制器的方法,如果访问的是 jsp、html、css、image或者js是不会进行拦截的
    • 细节:他也是AOP思想的具体应用
    • 想要自定义拦截器,必须要求实现:HandlerInterceptor接口

    在这里插入图片描述

    • 自定义拦截器的步骤

      • 编写自定义拦截器
      package com.mvc.interceptor;
      
      import org.springframework.web.servlet.HandlerInterceptor;
      
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      
      /**
       * @Author: 东方老赢
       * @Date: 2020/4/23 18:01
       */
      public class MyIntercepter1 implements HandlerInterceptor {
      
          /**
           * 预处理,controller方法执行前
           * return true:放行,执行下一个拦截器。如果没有,执行conroller方法
           * return false:不放行
           *
           * @param request
           * @param response
           * @param handler
           * @return
           * @throws Exception
           */
          @Override
          public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
              System.out.println("Interceptor运行成功");
              return true;
          }
      }
      
      • 配置拦截器(springmvc.xml)
      <!--配置拦截器-->
          <mvc:interceptors>
          <!--配置单个拦截器-->
              <mvc:interceptor>
              <!--要拦截的具体方法
                      path = /user/* 表示拦截当前类下的所有方法
                      path = /**  表示拦截所有方法-->
                  <mvc:mapping path="/user/*"/>
                      <!--不要拦截的方法-->
                  <!--<mvc:exclude-mapping path=""/>-->
                      <!--配置拦截器对象-->
                  <bean class="com.mvc.interceptor.MyIntercepter1"></bean>
              </mvc:interceptor>
          </mvc:interceptors>
      

      运行测试
      在这里插入图片描述



    • 拦截器中的方法

    1. preHandle:是controller方法执行之前拦截的方法
      • 可以使用request或者response跳转到指定页面
      • return true放行,执行下一个拦截器,如果没有拦截器,则直接执行controller中的方法
      • return false 不放行,不会执行controller中的方法
    2. postHandle:是controller方法执行后执行的方法,在JSP视图执行前
      • 可以使用request或者response跳转到指定页面
      • 如果指定了跳转的页面,那么controller方法跳转的页面将不会显示


第三篇 重头戏:SSM整合

  • 搭建整合环境

    • 整合说明:SSM整合可以用多种形式,这里选用XML+注解方式
      在这里插入图片描述
  1. 首先创建一个数据库

    	CREATE TABLE ssm(
    	    id  INT PRIMARY KEY AUTO_INCREMENT,
    	    NAME VARCHAR(20),
    	    money DOUBLE
    	);
    
  2. 创建Maven工程,导包

     <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <spring.version>5.0.2.RELEASE</spring.version>
        <mysql.version>5.1.6</mysql.version>
        <mybatis.version>3.4.5</mybatis.version>
      </properties>
    
      <dependencies>
    <!--    spring-->
          <!--AOP相关技术-->
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.6.8</version>
        </dependency>
    
          <!--AOPjar包-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
          <!--context容器-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
          <!--mvc相关jar包-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-web</artifactId>
          <version>${spring.version}</version>
        </dependency>
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-webmvc</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
          <!--单元测试-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-test</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
          <!--事务-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-tx</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
          <!--JDBC技术-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-jdbc</artifactId>
          <version>${spring.version}</version>
        </dependency>
    
          <!--单元测试-->
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>compile</scope>
        </dependency>
    
          <!--Mysql驱动jar包-->
        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>${mysql.version}</version>
        </dependency>
    
          <!--Servlet相关jar包-->
        <dependency>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
          <version>2.5</version>
          <scope>provided</scope>
        </dependency>
        <dependency>
          <groupId>javax.servlet.jsp</groupId>
          <artifactId>jsp-api</artifactId>
          <version>2.0</version>
          <scope>provided</scope>
        </dependency>
    
          <!--页面 el、jstl表达式-->
        <dependency>
          <groupId>jstl</groupId>
          <artifactId>jstl</artifactId>
          <version>1.2</version>
        </dependency>
    
    <!--      log  strat-->
          <dependency>
              <groupId>log4j</groupId>
              <artifactId>log4j</artifactId>
              <version>1.2.17</version>
          </dependency>
          <dependency>
              <groupId>org.slf4j</groupId>
              <artifactId>slf4j-log4j12</artifactId>
              <version>1.7.12</version>
          </dependency>
    <!--      log  end-->
    
          <!--Mybatis相关jar包组件-->
          <dependency>
              <groupId>org.mybatis</groupId>
              <artifactId>mybatis</artifactId>
              <version>${mybatis.version}</version>
          </dependency>
    
          <!--spring整合mybatis所需jar包-->
          <dependency>
              <groupId>org.mybatis</groupId>
              <artifactId>mybatis-spring</artifactId>
              <version>1.3.0</version>
          </dependency>
    
          <!--数据库连接池:c3p0-->
          <dependency>
              <groupId>c3p0</groupId>
              <artifactId>c3p0</artifactId>
              <version>0.9.1.1</version>
              <type>jar</type>
              <scope>compile</scope>
          </dependency>
    
      </dependencies>
    
  3. 搭建环境
    在这里插入图片描述

  • Spring框架代码的编写

    • 配置文件:

      <?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"
             xmlns:tx="http://www.springframework.org/schema/tx"
             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
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx.xsd">
      
      <!--    开启注解扫描 只需要处理service和dao-->
          <context:component-scan base-package="com.ssm">
      <!--        配置哪些注解不扫描-->
              <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
          </context:component-scan>
      </beans>
      
      
    • 编写代码测试

      @Service("accountService")
      public class AccountServiceImpl implements IAccountService {
          @Override
          public List<Account> findAll() {
              System.out.println("业务层,查询所有。。。");
              return null;
          }
      
          @Override
          public void saveAccount(Account account) {
              System.out.println("业务层,保存账户。。。");
          }
      }
      
      public class TestSpring {
      
          @Test
          public void run1(){
              ApplicationContext ac = new ClassPathXmlApplicationContext("SpringConfig.xml");
              IAccountService accountService = (IAccountService) ac.getBean("accountService");
              accountService.findAll();
          }
      }
      

    运行结果:通过
    在这里插入图片描述

  • Spring整合SpringMVC框架

    • 首先编写SpringMVC框架(详情见上)

      • 细节:springmvc.xml配置注解扫描
      <!--    开启注解扫描,只扫描Controller注解-->
          <context:component-scan base-package="com.ssm">
              <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
          </context:component-scan>
      
      
    • 然后开始整合

      <!--  配置spring的监听器,默认只加载WEB-INF目录下的配置文件-->
        <listener>
          <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <!--  但是由于SpringConfig.xml配置文件不在WEB-INF目录下,所以需要指定路径-->
        <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>classpath:SpringConfig.xml</param-value>
        </context-param>
      
      @Controller
      @RequestMapping("/account")
      public class AccountController {
      
          @Autowired
          private IAccountService accountService;
      
          @RequestMapping("/findAll")
          public String findAll(){
              System.out.println("表现层:查询所有。。。");
              accountService.findAll();
              return "success";
          }
      }
      
    • 运行结果
      在这里插入图片描述

  • Spring整合Mybatis框架

    • 首先编写Mybatis框架,详情见:如果你读完这篇文章,恭喜你!你的Mybatis入门了!

    • 测试通过后开始整合(在SpringConfig.xml中整合)

      <!--Spring整合Mybatis框架-->
          <!--配置连接池-->
          <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
              <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
              <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring"></property>
              <property name="user" value="root"></property>
              <property name="password" value="123456"></property>
          </bean>
          <!--配置SqLSessionFactory工厂-->
          <bean id="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <property name="dataSource" ref="dataSource"></property>
          </bean>
      
          <!--配置AccountDao接口所在包-->
          <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <property name="basePackage" value="com.ssm.dao"></property>
          </bean>
      
      @Service("accountService")
      public class AccountServiceImpl implements IAccountService {
          @Autowired
          private IAccountDao accountDao;
      
          @Override
          public List<Account> findAll() {
              System.out.println("业务层,查询所有。。。");
              return accountDao.findAll();
          }
      
          @Override
          public void saveAccount(Account account) {
              System.out.println("业务层,保存账户。。。");
              accountDao.saveAccount(account);
          }
      }
      
      @Controller
      @RequestMapping("/account")
      public class AccountController {
      
          @Autowired
          private IAccountService accountService;
      
          @RequestMapping("/findAll")
          public String findAll(Model model){
              System.out.println("表现层:查询所有。。。");
              List<Account> list = accountService.findAll();
              model.addAttribute("list",list);
              return "success";
          }
      }
      
      
      <%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
      <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
      <html>
      <head>
          <title>Title</title>
      </head>
      <body>
          成功
          <c:forEach items="${list}" var="account">
              ${account.name}
              ${account.money}
          </c:forEach>
      </body>
      </html>
      

    运行结果:
    在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值