SSM框架专题-从零入门SpringMVC笔记

一、Spring概述

1. SSM框架优化的方向

图解:
MyBatis是对数据访问层的优化
SpringMVC是对控制器的优化
Spring框架时管理其他框架的框架
在这里插入图片描述

2.SpringMVC框架的优点

  1. 轻量级,基于MVC的框架
  2. 易于上手,容易理解,功能强大
  3. 它具备IOC和AOP
  4. 完全基于注解开发

3. 时序图解析

可以从图上看出,SpringMVC对控制器的优化
在这里插入图片描述

4.SpringMVC的执行流程

一个好汉三个帮:
DispatcherServlet是核心

4.分析web请求
  web请求执行的流程
  							    核心处理器
  index.jsp<--------------->DispatcherServlet<------------------->SpringMVC的处理器是一个普通的方法
  one.jsp  <--------------->DispatcherServlet<------------------->SpringMVC的处理器是一个普通的方法

在这里插入图片描述

二、SpringMVC注解式开发

1. @RequestMapping功能

可以放在方法上或者放在类上
目的是为了可以让你访问到服务器的资源

执行顺序:

  1. 前端点击超链接
  <a href="${pageContext.request.contextPath}/a/demo.action">访问服务器1</a>
  1. 被DispatcherServlet拦截,如果是/a/demo.action则进入action类
@Controller
@RequestMapping("/a")
public class DemoAction {
    
    
    /**
     * action中的规范
     * public
     * 返回值任意
     * 名字任意
     * 参数任意
     * 需要@RequestMapping()
     */
    @RequestMapping("/demo")
    public String demo(){
    
    
        System.out.println("访问了a的demo");
        return "main";
    }
}
  1. 经过包扫描,controller类自动添加前后缀
    <!--添加包扫描-->
    <context:component-scan base-package="com.powernode.springmvc.controller"></context:component-scan>
    <!--添加视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--添加前缀-->
        <property name="prefix" value="/admin/"></property>
        <!--添加后缀-->
        <property name="suffix" value=".jsp"></property>
    </bean>
  1. 最后返回到main中,加上前缀后缀/admin/main.jsp

2.识别get还是post

    @RequestMapping(value = "/demo",method = RequestMethod.GET)
    public String req1(){
    
    
        System.out.println("我是处理get请求的");
        return "main";
    }

    @RequestMapping(value = "/demo",method = RequestMethod.POST)
    public String req2(){
    
    
        System.out.println("我是处理post请求的");
        return "main";
    }

3.五种数据提交的方式

第1种:单个数据提交

在form表单中,对应的name即是后台Controller的参数

  <h1>五种数据提交的方式</h1>
    <form action="${pageContext.request.contextPath}/datasubmit.action" method="post">
      名字:<input type="text" name="name"><br>
      年龄:<input type="text" name="age"><br>
      <input type="submit">
    </form>
    @RequestMapping("datasubmit")
    public String one(String name,Integer age){
    
    
        System.out.println("名字是:"+name+",年龄为:"+age);
        return "main";
    }

第2种:对象封装提交数据

    <h1>第二种提交方式,对象封装提交</h1>
    <form action="${pageContext.request.contextPath}/two.action">
      名字:<input type="text" name="user"><br>
      年龄:<input type="text" name="age"><br>
      <input type="submit">
    </form>

第3种:动态占位符提交数据(从路径中)

在html中用 斜杆+值提交,后台用斜杆+大括号接收数据,在后台参数位置加上@PathVariable接收

    <h1>第三种提交方式,动态占位符提交</h1>
    <form action="${pageContext.request.contextPath}/three/林泽培/20.action">
      <input type="submit">
    </form>
    @RequestMapping("/three/{name}/{age}")
    public String three(@PathVariable String name,@PathVariable int age){
    
    
        System.out.println(name+","+age);
        return "main";
    }

第4种:前端页面参数与后端不一致

遇到前端参数与后端不一致的情况,我们可以使用@RequestParm起别名

    <h1>第四种提交方式,前端参数与后端不一致</h1>
    <form action="${pageContext.request.contextPath}/fore.action">
      名字:<input type="text" name="name"><br>
      年:<input type="text" name="age"><br>
      <input type="submit">
    </form>
    /**
     * 双引号内填写前端参数名称
     *
     * @param uname
     * @param uname
     * @return
     */
    @RequestMapping("/fore")
    public String fore(@RequestParam("name") String uname, @RequestParam("age") int uage) {
    
    
        System.out.println(uname + "," + uage);
        return "main";
    }

第5种:手工提取参数

使用古老的Servlet技术,提取request参数获取值

    <h1>第五种提交方式,request提取参数</h1>
    <form action="${pageContext.request.contextPath}/five.action">
      名字:<input type="text" name="name"><br>
      年龄:<input type="text" name="age"><br>
      <input type="submit">
    </form>
    @RequestMapping("/five")
    public String five(ServletRequest request){
    
    
        String name = request.getParameter("name");
        Integer age = Integer.parseInt(request.getParameter("age"));
        System.out.println(name+age);
        return "main";
    }

8. 中文编码设置

    <!--设置中文过滤器-->
    <filter>
        <!--过滤器名称-->
        <filter-name>encode</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>
        <init-param>
            <param-name>forceRequestEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>forceResponseEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encode</filter-name>
        <!--作用域-->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

9. action方法的返回值

  1. String:客户端资源的地址,自动拼接前缀和后缀.还可以屏蔽自动拼接字符串,可以指定返回的路径.
  2. Object:返回json格式的对象.自动将对象或集合转为json.使用的jackson工具进行转换,必须要添加jackson依赖.一般用于ajax请求.
  3. void:无返回值,一般用于ajax请求.
  4. 基本数据类型,用于ajax请求.
  5. ModelAndView:返回数据和视图对象,现在用的很少.

10.ajax请求json数组功能实现

  <a href="javascript:showStu()">访问服务器返回学生集合</a>
  <div id="mydiv">等待服务器返回数据</div>

  <script type="text/javascript">
    function showStu() {
      
      
      //使用jQuery封装的ajax()方法发送请求
      $.ajax({
      
      
        url:"${pageContext.request.contextPath}/list.action",
        type:"get",
        dataType:"json",
        success:function(stuList) {
      
      
          var s = "";
          $.each(stuList,function(i,stu) {
      
      
            s+=stu.name + "----" + stu.age+"<br>";
          });
          //回显数据
          $("#mydiv").html(s);
        }
      })
    }
  </script>
@Controller
public class StudentListAction {
    
    
    @RequestMapping("/list")
    @ResponseBody //解析ajax,必须在springmvc.xml中配置
    public List<Student> list(){
    
    
        Student stu1 = new Student("李白",21);
        Student stu2 = new Student("林白",22);
        Student stu3 = new Student("白白",23);
        List<Student> students = new ArrayList<>();
        students.add(stu1);
        students.add(stu2);
        students.add(stu3);
        //返回的学生数组,springmvc自动转成json格式
        return students;
    }
}

11.请求转发和重定向的区别

请求转发:是基于服务端的跳转,因此显示的URL还是xx.action
重定向:是基于客户端的跳转,等同于重新访问一个网址,所以URL为正常
在这里插入图片描述

  <a href="${pageContext.request.contextPath}/one.action"><h1>方法1:请求转发</h1></a>
  <a href="${pageContext.request.contextPath}/two.action"><h1>方法2:请求转发action</h1></a>
  <a href="${pageContext.request.contextPath}/three.action"><h1>方法3:重定向</h1></a>
  <a href="${pageContext.request.contextPath}/fore.action"><h1>方法4:重定向action</h1></a>
  <a href="${pageContext.request.contextPath}/five.action"><h1>方法5:随便访问</h1></a>

@Controller
public class JumpAction1 {
    
    

    /**
     * 方法1:请求转发(默认)
     * @return
     */
    @RequestMapping("/one")
    public String one(){
    
    
        return "main";
    }

    /**
     * 方法2:请求转发action
     * @return
     */
    @RequestMapping("/two")
    public String two(){
    
    
        return "forward:/haha.action";
    }

    /**
     * 方法3:重定向
     * @return
     */
    @RequestMapping("/three")
    public String three(){
    
    
        return "redirect:/admin/main.jsp";
    }

    /**
     * 方法4:重定向action
     * @return
     */
    @RequestMapping("/fore")
    public String fore(){
    
    
        return "redirect:/haha.action";
    }


    /**
     * 方法5:随便访问一个
     */
    @RequestMapping("/five")
    public String five(){
    
    
        return "redirect:/aaa.jsp";
    }
}

12. 默认参数传递数据

    /**
     * 带参数跳转到页面,请求转发到页面
     * 只能用请求转发,如果用重定向会导致参数丢失(除了session
     * @return
     */
    @RequestMapping("/six")
    public String six(HttpServletRequest request,
                      HttpServletResponse response,
                      Map map,
                      Model model,
                      HttpSession session){
    
    
        User u = new User("王无",21);
        request.setAttribute("user1",u);
        map.put("user2",u);
        model.addAttribute("user3",u);
        session.setAttribute("user4",u);
        return "main";
    }
<html>
  <head>
    <title>Title</title>
  </head>
  <body>
  ${user1}
  ${user2}
  ${user3}
  ${user4}
  main,....
  </body>
</html>

13.单个日期注入

在springmvc中,前端传来的日期会被当成字符串传过来,所以我们在后端接收到要使用注解@DateTimeFormat,此注解必须搭配springmvc.xml文件中的mvc:annotationdriven标签

  <form action="${pageContext.request.contextPath}/datesubmit.action">
    日期:<input type="date" name="date">
    <input type="submit">
  </form>
    @RequestMapping("/datesubmit")
    public String datesubmit(@DateTimeFormat(pattern = "yyyy-MM-dd") Date date){
    
    
        System.out.println(date);
        return "forward:/aaa.jsp";
    }

14. 多个日期格式转换

注册一个注解,用来解析本类中所有的日期类型,自动转换.

    /**
     * 绑定全局日期格式转换
     * @param dataBinder
     */
    @InitBinder
    public void initBinder(WebDataBinder dataBinder){
    
    
        dataBinder.registerCustomEditor(
                Date.class,new CustomDateEditor(
                        new SimpleDateFormat("yyyy-MM-dd"),true
                )
        );
    }

    @RequestMapping("/datesubmit")
    public String datesubmit(Date date){
    
    
        System.out.println(date);
        return "forward:/aaa.jsp";
    }

15.日期的显示处理

在页面上显示好看的日期,必须使用JSTL.
步骤:
A)添加依赖jstl

      <dependency>
      <groupId>jstl</groupId>
      <artifactId>jstl</artifactId>
      <version>1.2</version>
    </dependency>
B)在页面上导入标签库 
如果是单个日期对象,直接转为好看的格式化的字符串进行显示.
如果是list中的实体类对象的成员变量是日期类型,则必须使用jstl进行显示.
    <%--导入jstl核心标签库--%>
	<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
	<%--导入jstl格式化标签库--%>
	<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
C)使用标签显示数据    
 <table width="800px" border="1">
    <tr>
        <th>姓名</th>
        <th>生日</th>
    </tr>
    	<c:forEach items="${list}" var="stu">
    <tr>
            <td>${stu.name}</td>
            <td>${stu.birthday}------ <fmt:formatDate value="${stu.birthday}" pattern="yyyy-MM-dd"></fmt:formatDate></td>
    </tr>
    	</c:forEach>
	</table>

16. springMVC流程复习

在这里插入图片描述

  1. DispatcherServlet接收到用户请求,开始解析数据
  2. 通过HandlerMapping解析出demo
  3. 通过HandlerAdapter判断是bean还是xml
  4. 创建对应的controller,进行(业务逻辑、数据访问层,如果有),处理完返回值给ModelAndView
  5. 返回值若是main,把值传给ViewResolver进行拼接,返回给核心处理器
  6. DispatcherServlet控制view显示给用户什么页面

17. 资源在WEB-INF目录下.

此目录下的动态资源,不可直接访问,只能通过请求转发的方式进行访问 .

  @Controller
	public class WebInfAction {
    
    
	    @RequestMapping("/showIndex")
	    public String showIndex(){
    
    
	        System.out.println("访问index.jsp");
	        return "index";
	    }
	    @RequestMapping("/showMain")
	    public String showMain(){
    
    
	        System.out.println("访问main.jsp");
	        return "main";
	    }
	    @RequestMapping("/showLogin")
	    public String showLogin(){
    
    
	        System.out.println("访问login.jsp");
	        return "login";
	    }
	    //登录的业务判断
	    @RequestMapping("/login")
	    public String login(String name, String pwd, HttpServletRequest request){
    
    
	        if("zar".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){
    
    
	            return "main";
	        }else{
    
    
	            request.setAttribute("msg","用户名或密码不正确!");
	            return "login";
	        }
	    }
	}

三. SpringMVC的拦截器

1.概述

针对请求和响应进行的额外的处理.在请求和响应的过程中添加预处理,后处理和最终处理.

2. 拦截器执行的时机

  1. preHandle():在请求被处理之前进行操作,预处理
  2. postHandle():在请求被处理之后,但结果还没有渲染前进行操作,可以改变响应结果,后处理
  3. afterCompletion:所有的请求响应结束后执行善后工作,清理对象,关闭资源 ,最终处理.

3.拦截器实现的两种方式

  1. 继承HandlerInterceptorAdapter的父类
  2. 实现HandlerInterceptor接口,实现的接口,推荐使用实现接口的方式

4.拦截器的步骤

  1. 改造登录方法,在session中存储用户信息,用于进行权限验证
  @RequestMapping("/login")
    public String login(String name, String pwd, HttpServletRequest request){
    
    
        if("zar".equalsIgnoreCase(name) && "123".equalsIgnoreCase(pwd)){
    
    
            //在session中存储用户信息,用于进行权限验证
            request.getSession().setAttribute("users",name);
            return "main";
        }else{
    
    
            request.setAttribute("msg","用户名或密码不正确!");
            return "login";
        }
    }
  1. 开发拦截器的功能.实现HandlerInterceptor接口,重写preHandle()方法
    if(request.getSession().getAttribute("users") == null){
    
    
            //此时就是没有登录,打回到登录页面,并给出提示
            request.setAttribute("msg","您还没有登录,请先去登录!");
            request.getRequestDispatcher("/WEB-INF/jsp/login.jsp").forward(request,response);
            return false;
        }
        return true;//放行请求
  1. 在springmvc.xml文件中注册拦截器
  	<mvc:interceptors>
        <mvc:interceptor>
            <!--映射要拦截的请求-->
            <mvc:mapping path="/**"/>
            <!--设置放行的请求-->
            <mvc:exclude-mapping path="/showLogin"></mvc:exclude-mapping>
            <mvc:exclude-mapping path="/login"></mvc:exclude-mapping>
            <!--配置具体的拦截器实现功能的类-->
            <bean class="com.bjpowernode.interceptor.LoginInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>

四、SSM搭建

  • controller层即配置mvc相关的内容,包括扫描加有@Controller注解的类所在包、一个好汉(核心servlet)三个帮的三个帮手,并在web.xml中注册核心servlet
  • service层就是业务层,包括主业务(包扫描)和切面业务(aop)相关,这里事务是一种切面业务
  • dao层数据访问层,因为整合了mybatis,所以配置sqlsessionbuildFactory(需要mybatis配置+数据源(因为数据源交给spring管理,不再在mybatis中配置))

1.SSM整合的步骤

  1. 建库,建表
  2. 新建Maven项目,选择webapp模板
  3. 修改目录
  4. 修改pom.xml文件(使用老师提供)
  5. 添加jdbc.properties属性文件
  6. 添加SqlMapConfig.xml文件(使用模板)
  7. 添加applicationContext_mapper.xml文件(数据访问层的核心配置文件)
  8. 添加applicationContext_service.xml文件(业务逻辑层的核心配置文件)
  9. 添加spirngmvc.xml文件
  10. 删除web.xml文件,新建,改名,设置中文编码,并注册spirngmvc框架,并注册Spring框架
  11. 新建实体类user
  12. 新建UserMapper.java接口
  13. 新建UserMapper.xml实现增删查所有功能,没有更新
  14. 新建service接口和实现类
  15. 新建测试类,完成所有功能的测试
  16. 新建控制器,完成所有功能
  17. 浏览器测试功能

2.什么是跨域访问

前端是8082端口,后端是8080端口
这称之为跨端口
跨端口是跨域的一种
跨协议也是跨域的一种
不同的服务器,跨服务也是跨域的一种

@CrossOrigin //服务器跨域访问

猜你喜欢

转载自blog.csdn.net/u011005040/article/details/127467354