[Java]SpringMVC 学习笔记(动力节点王鹤王妈妈2020)(四)

简介: [Java]SpringMVC 学习笔记(动力节点王鹤王妈妈2020)(四)

Dao

  • 操作数据库的接口定义:StudentDao
/**
 * ClassName: StudentDao
 * Package: cw.springmvc.study.dao
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-28 15:57
 * @Version 1.0
 */
public interface StudentDao {
    /**
     * 插入学生信息
     * 
     * @param student 学生信息
     * @return 影响数据库的条数
     */
    int insertStudent(Student student);
    /**
     * 查询全部学生信息
     * 
     * @return 学生信息
     */
    List<Student> selectStudents();
}
  • SQL映射配置文件:StudentDao
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cw.springmvc.study.dao.StudentDao">
  <insert id="insertStudent">
    insert into t_student(name, age)
    values (#{name}, #{age});
  </insert>
  <select id="selectStudents" resultType="Student">
    select id, name, age from t_student order by id desc;
  </select>
</mapper>

Service

  • 业务层接口:StudentService
package cw.springmvc.study.service;
import cw.springmvc.study.pojo.Student;
import java.util.List;
/**
 * ClassName: StudentService
 * Package: cw.springmvc.study.service
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-28 16:05
 * @Version 1.0
 */
public interface StudentService {
    /**
     * 添加学生信息
     *
     * @param student 学生信息
     * @return
     */
    int addStudent(Student student);
    /**
     * 查询所有学生信息
     *
     * @return 学生信息
     */
    List<Student> findStudents();
}
  • 业务层接口实现类:StudentServiceImpl
package cw.springmvc.study.service.impl;
import cw.springmvc.study.dao.StudentDao;
import cw.springmvc.study.pojo.Student;
import cw.springmvc.study.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
 * ClassName: StudentServiceImpl
 * Package: cw.springmvc.study.service.impl
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-28 16:07
 * @Version 1.0
 */
@Service
public class StudentServiceImpl implements StudentService {
    @Autowired // 根据类型自动装配
    private StudentDao studentDao;
    @Override
    public int addStudent(Student student) {
        return studentDao.insertStudent(student);
    }
    @Override
    public List<Student> findStudents() {
        return studentDao.selectStudents();
    }
}

controller

package cw.springmvc.study.controller;
import cw.springmvc.study.pojo.Student;
import cw.springmvc.study.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.List;
/**
 * ClassName: StudentController
 * Package: cw.springmvc.study.controller
 * Description:
 *
 * @Author tcw
 * @Create 2023-06-05 18:33
 * @Version 1.0
 */
@Controller
@RequestMapping("/student")
public class StudentController {
    @Autowired // 自动装配
    private StudentService studentService;
    /**
     * 处理新增学生信息请求
     *
     * @return 视图和数据
     */
    @RequestMapping("/add")
    public ModelAndView addStudent(Student student) {
        // 调用Service处理新增学生信息业务
        int cnt = studentService.addStudent(student);
        ModelAndView mv = new ModelAndView();
        // 添加响应数据
        if (cnt > 0) {
            mv.addObject("msg", "学生【" + student.getName() + "】注册成功");
        } else {
            mv.addObject("msg", "学生【" + student.getName() + "】注册失败");
        }
        // 设置响应视图
        mv.setViewName("result");
        return mv;
    }
    /**
     * 查询所有的学生信息
     *
     * @return 所有的学生信息
     */
    @RequestMapping("/list")
    @ResponseBody
    public List<Student> selectStudentAll() {
        // 查询学生信息
        return studentService.findStudents();
    }
}

JSP

  • index.jsp
<%--
  Created by IntelliJ IDEA.
  User: cw
  Date: 2023-06-05
  Time: 18:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.js"></script>
    <script>
        $(function () {
            $("button").click(function (){
                // 发请求
                $.ajax({
                    url: "./student/list",
                    type:"get",
                    dataType:"json",
                    success(data) {
                        let newData = data.map((d) => {
                            return d.id + " " + d.name + " " + d.age + "<br/>";
                        })
                        $("div").html(""); // 清除
                        $("div").append(newData); // 追加新数据
                    }
                })
            })
        })
    </script>
</head>
<body>
<p>SSM</p>
<form action="./student/add" method="post">
    姓名:<input name="name" type="text"><br/>
    年龄:<input name="age" type="text"><br/>
    <input value="提交" type="submit">
</form>
<br/>
<button>查询学生信息</button>
<div></div>
</body>
</html>
  • result.jsp
<%--
  Created by IntelliJ IDEA.
  User: cw
  Date: 2023-06-05
  Time: 18:41
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
  <h2>${msg}</h2>
</body>
</html>

测试

请求转发与重定向

  • SpringMVC 框架把原来 Servlet 中的请求转发和重定向操作进行了封装。可以使用简单的方式实现转发和重定向。
  • 使用 forward 表示转发,实现 request.getRequestDispatcher(“xx.jsp”).forward()
  • 使用 redirect 表示重定向,实现 response.sendRedirect(“xxx.jsp”)
  • forward 和 redirect 都是 SpringMVC 框架中的关键字,两个关键字都不和视图解析器一同工作

请求转发

  • 通过处理器方法返回ModelAndView,实现请求转发
  • 语法:
mv.setViewName("forward:视图文件完整路径")
  • 注意:forward 不和视图解析器一同使用,不管有没有配置视图解析器,使用forward进行请求转发都相当于没有视图解析器。
  • 使用 forward 关键字进行请求转发为显示转发,该种方式主要用于当想要进行请求转发但是要转发到的页面没有在视图解析器配置的路径中的情况下,使得请求转发可以不受视图解析器的限制,实现可以转发到视图解析器以外的页面
  • 视图解析器配置如下:
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/WEB-INF/"/>
  <property name="suffix" value=".jsp"/>
</bean>
  • 控制器:
@Controller
public class MyController {
    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(String name, String age) {
        ModelAndView mv = new ModelAndView();
        System.out.println(123);
        mv.addObject("name", name);
        mv.addObject("age", age);
        // 进行请求转发
        mv.setViewName("forward:./WEB-INF/view/show.jsp");
        return mv;
    }
}
  • show.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<p>姓名:${name}</p>
<p>年龄:${age}</p>
</body>
</html>

请求重定向

  • 通过处理器方法返回ModelAndView,实现请求重定向
  • 语法:
mv.setViewName("redirect:视图文件完整路径")
  • 注意:redirect 不和视图解析器一同使用,不管有没有配置视图解析器,使用redirect进行请求重定向都相当于没有视图解析器。
  • 控制器:
@Controller
public class MyController {
    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(String name, String age) {
        ModelAndView mv = new ModelAndView();
        mv.addObject("name111", name);
        mv.addObject("age111", age);
        System.out.println("name: " + name + " age: " + age);
        // 进行请求重定向
        // http://localhost:8080/springmvc/show222.jsp?name111=%E5%BC%A0%E4%B8%89&age111=23
        mv.setViewName("redirect:./show222.jsp");
        return mv;
    }
}
  • 在进行请求重定向的时候,添加到ModelAndView中的数据,框架会将Model中的简单类型的数据转为String使用,作为向请求重定向地址的请求参数使用,使得在两次请求之间可以传递数据
  • 注意:请求重定向是一次全新的从浏览器发出的请求,WEB-INF下的资源是不能被浏览器请求访问的
  • jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<!--
    请求重定向,是全新的一次请求,参数在request对象上,
    不在本次的请求作用域中
-->
<!-- param 请求参数集合 -->
<p>姓名:${param.name111}</p>
<p>年龄:<%= request.getParameter("age111") %></p>
</body>
</html>

异常处理

  • 之前对代码可能出现异常的处理方法:
public void fun() {
  try {
    } catch (Exception e){
    }
}
  • SpringMVC 框架中将处理异常的代码(非业务逻辑代码)抽取出来,在一个统一的位置定义异常的处理,采用面向切面编程的方式,来处理异常
  • springmvc框架采用的是统一,全局的异常处理。把controller中的所有异常处理都集中到一个地方,采用的是aop的思想,把业务逻辑和异常处理代码分开,解耦合。
  • springmvc框架提供了两个注解进行异常的处理:@ExceptionHandler、@ControllerAdvice

自定义异常类

package cw.springmvc.exception;
/**
 * ClassName: MyUserException
 * Package: cw.springmvc.exception
 * Description:
 *
 * @Author tcw
 * @Create 2023-06-05 22:31
 * @Version 1.0
 */
public class MyUserException extends Exception{
    public MyUserException() {
        super();
    }
    public MyUserException(String message) {
        super(message);
    }
}
package cw.springmvc.exception;
/**
 * ClassName: AgeException
 * Package: cw.springmvc.exception
 * Description:
 *
 * @Author tcw
 * @Create 2023-06-05 22:32
 * @Version 1.0
 */
public class AgeException extends MyUserException{
    public AgeException() {
        super();
    }
    public AgeException(String message) {
        super(message);
    }
}
package cw.springmvc.exception;
/**
 * ClassName: NameException
 * Package: cw.springmvc.exception
 * Description:
 *
 * @Author tcw
 * @Create 2023-06-05 22:32
 * @Version 1.0
 */
public class NameException extends MyUserException{
    public NameException() {
        super();
    }
    public NameException(String message) {
        super(message);
    }
}

处理器类

package cw.springmvc.controller;
import cw.springmvc.exception.AgeException;
import cw.springmvc.exception.MyUserException;
import cw.springmvc.exception.NameException;
import cw.springmvc.pojo.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.sound.midi.Soundbank;
import java.util.ArrayList;
import java.util.List;
/**
 * ClassName: MyController
 * Package: cw.springmvc.controller
 * Description:
 *
 * @Author tcw
 * @Create 2023-05-21 20:24
 * @Version 1.0
 */
@Controller
public class MyController {
    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(String name, Integer age) throws MyUserException {
        ModelAndView mv = new ModelAndView();
        // 根据请求参数抛出异常,将异常交给SpringMVC框架处理
        if (!"admin".equals(name)) {
            throw new NameException("用户名不正确.");
        }
        if (age == null || age < 0) {
            throw new AgeException("年龄不正确.");
        }
        mv.addObject("name", name);
        mv.addObject("age", age);
        mv.setViewName("show");
        return mv;
    }
}

异常处理器

  • 当控制器发生异常时,会停止控制器方法的执行,跳转到异常处理器类中,进行处理异常方法的匹配
  • 异常处理类,也是组件,所以需要配置包扫描,进行异常处理类组件扫描
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
    @AliasFor("basePackages")
    String[] value() default {};
    @AliasFor("value")
    String[] basePackages() default {};
    Class<?>[] basePackageClasses() default {};
    Class<?>[] assignableTypes() default {};
    Class<? extends Annotation>[] annotations() default {};
}
  • @ControllerAdvice:标注该类是异常处理类
  • @ExceptionHandler:标注异常处理方法处理的异常类型,如果没有指定处理的异常类型,那么该方法就是用于处理没有异常处理方法匹配的异常,没有指定处理的异常类型的方法只能有一个
  • 要使用这两个注解,需要在SpringMVC配置文件中配置注解驱动
package cw.springmvc.handler;
import cw.springmvc.exception.AgeException;
import cw.springmvc.exception.NameException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;
/**
 * ClassName: GlobalExceptionHandler
 * Package: cw.springmvc.handler
 * Description:
 * 全局异常处理器
 * ControllerAdvice注解:控制器通知、控制器增强
 * 给控制器增加功能,增加异常处理功能
 * ControllerAdvice注解使用在类上
 * 对于控制器通知组件需要配置组件扫描器
 *
 * @Author tcw
 * @Create 2023-06-05 22:39
 * @Version 1.0
 */
// 标注为控制器异常处理组件
@ControllerAdvice
public class GlobalExceptionHandler {
    /**
     * 定义方法,处理发生的异常
     * 处理异常的方法和控制器方法的定义方式一样,
     * 控制器方法可以怎么定义,处理异常的方法就可以怎么定义
     *
     * 处理NameException的异常
     *
     * @param e 表示Controller中抛出的异常对象
     *          通过这个形参可以获取发生的异常信息
     * @return
     */
    // @ExceptionHandler(异常的class):表示该方法处理异常的类型
    @ExceptionHandler(value = {NameException.class})
    public ModelAndView doNameException(Exception e) {
        // 异常的处理逻辑:
        // 1.需要把异常记录下来,记录到数据库或日志文件
        //   记录日志发生的时间、哪个方法发生、异常错误的内容
        // 2.发送通知,把异常的信息通过邮件、短信、微信发送给相关人员
        // 3.给用户友好的提示
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "用户名必须是admin");
        mv.addObject("exception", e);
        mv.setViewName("nameError");
        return mv;
    }
    /**
     * 处理年龄异常 AgeException
     *
     * @param e 异常对象
     * @return
     */
    @ExceptionHandler(value = {AgeException.class})
    public ModelAndView doAgeException(Exception e) {
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "年龄不能为空,且应该大于0");
        mv.addObject("exception", e);
        mv.setViewName("ageError");
        return mv;
    }
    /**
     * 处理其他异常,处理没有相匹配的异常处理方法的异常
     * 会先与有指定处理具体异常的方法进行匹配,都不能处理发生的异常
     * 即没有方法匹配
     * 就使用该方法进行处理,使用没有指定具体处理异常类型的方法处理
     * 只能有一个默认处理异常的
     *
     * @param e 异常对象
     * @return
     */
    @ExceptionHandler
    public ModelAndView doOtherException(Exception e) {
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg", "未知异常");
        mv.addObject("exception", e);
        mv.setViewName("defaultError");
        return mv;
    }
}

JSP

  • show.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<p>姓名:${name}</p>
<p>年龄:${age}</p>
</body>
</html>
  • ageError.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>年龄异常</h1>
<p>${msg}</p>
<p>${exception.message}</p>
</body>
</html>
  • nameError.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>姓名异常</h1>
<p>${msg}</p>
<p>${exception.message}</p>
</body>
</html>
  • defaultError.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<h1>未知异常</h1>
<p>${msg}</p>
<p>${exception.message}</p>
</body>
</html>
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="./some.do" method="post">
    name:<input type="text" name="name"><br/>
    age:<input type="text" name="age"><br/>
    <input type="submit" name="submit"><br/>
</form>
</body>
</html>


相关文章
|
3月前
|
存储 Java
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
Java学习笔记 List集合的定义、集合的遍历、迭代器的使用
|
16天前
|
分布式计算 Java MaxCompute
ODPS MR节点跑graph连通分量计算代码报错java heap space如何解决
任务启动命令:jar -resources odps-graph-connect-family-2.0-SNAPSHOT.jar -classpath ./odps-graph-connect-family-2.0-SNAPSHOT.jar ConnectFamily 若是设置参数该如何设置
|
1月前
|
分布式计算 资源调度 Hadoop
大数据-01-基础环境搭建 超详细 Hadoop Java 环境变量 3节点云服务器 2C4G XML 集群配置 HDFS Yarn MapRedece
大数据-01-基础环境搭建 超详细 Hadoop Java 环境变量 3节点云服务器 2C4G XML 集群配置 HDFS Yarn MapRedece
76 4
|
1月前
|
分布式计算 Java Hadoop
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
Hadoop-30 ZooKeeper集群 JavaAPI 客户端 POM Java操作ZK 监听节点 监听数据变化 创建节点 删除节点
62 1
|
2月前
|
缓存 前端开发 Java
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
Soring Boot的起步依赖、启动流程、自动装配、常用的注解、Spring MVC的执行流程、对MVC的理解、RestFull风格、为什么service层要写接口、MyBatis的缓存机制、$和#有什么区别、resultType和resultMap区别、cookie和session的区别是什么?session的工作原理
【Java面试题汇总】Spring,SpringBoot,SpringMVC,Mybatis,JavaWeb篇(2023版)
|
2月前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
从Java环境的搭建到实际代码的编写,从基本用法的讲解到底层原理的剖析,深度解析Java基础知识。本文是《Java学习路线》专栏的起始文章,旨在提供一套完整的Java学习路线,覆盖Java基础知识、数据库、SSM/SpringBoot等框架、Redis/MQ等中间件、设计模式、架构设计、性能调优、源码解读、核心面试题等全面的知识点,并在未来不断更新和完善,帮助Java从业者在更短的时间内成长为高级开发。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(基础篇)
|
2月前
|
存储 安全 Java
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
本文是Java基础的进阶篇,对异常、集合、泛型、Java8新特性、I/O流等知识进行深入浅出的介绍,并附有对应的代码示例,重要的地方带有对性能、底层原理、源码的剖析。适合Java初学者。
Java修仙之路,十万字吐血整理全网最完整Java学习笔记(进阶篇)
|
1月前
|
Java 数据安全/隐私保护
java学习笔记(基础习题)
java学习笔记(基础习题)
33 0
|
1月前
|
Java 程序员 开发工具
java学习笔记
java学习笔记
34 0
|
2月前
|
JSON 前端开发 Java
【Java笔记+踩坑】SpringMVC基础
springmvc简介、入门案例、bean加载控制、PostMan工具的使用、普通和JSON和日期格式请求参数传递、响应JSON或jsp或文本、Rest风格
【Java笔记+踩坑】SpringMVC基础