Spring学习(7)——Spring与Web(整个项目使用 servlet ,spring + mybatis)

上次将SpringMybatis进行了整合,现在来尝试将这两个框架写一个简单的Web项目。

首先创建一个新的module

类型是 maven-archetype-webapp
定义一个学生Student表

将上个项目的代码全部导入

将 spring-mybatis 项目中以下内容复制到当前项目中:上个项目链接
(1)Service 层、Dao 层全部代码
(2)配置文件 applicationContext.xmljdbc.propertiesmybatis.xml
(3)pom.xml
(4)加入 servlet ,jsp 依赖

<!-- servlet依赖 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>

    <!-- jsp依赖 -->
    <dependency>
      <groupId>javax.servlet.jsp</groupId>
      <artifactId>jsp-api</artifactId>
      <version>2.2.1-b03</version>
      <scope>provided</scope>
    </dependency>

修改web.xml

用这个maven模板创建出来的webapp是2.3版本的,这个版本过低,甚至无法使用${},我们将其改为4.0版本的

先将原先的web.xml删除,点完 “—” 记得一定要点Apply! 不然你再点“+”添加时会失败
在这里插入图片描述
再点“+”号导入一个新的web.xml,选择4.0版本,再点Apply应用。

C V结束,开始新项目

创建servlet,这里教一个小技巧,可以一键创建servlet文件

右击你main / java下的第一个目录,比如我这里是com,就可以直接看到有这么一个选项能直接创建servlet(当然也能创建filter和listener文件)
在这里插入图片描述
点击“Create New Servlet”之后,会出现下面的弹窗,默认情况下是勾选使用注解方式创建,取消勾选则会在web.xml里面自动生成对应路径
在这里插入图片描述
我们取消勾选,web.xml里面自动增加了该servlet的路径信息
在这里插入图片描述
我们再加入相应的mapping标签

    <servlet-mapping>
        <servlet-name>RegisterServlet</servlet-name>
        <url-pattern>/reg</url-pattern>
    </servlet-mapping>

编写两个jsp,一个是注册页,一个是注册成功页面

index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册</title>
</head>
<body>
    <p>注册学生</p>
    <form action="reg" method="post">
        <table>
            <tr>
                <td>id:</td>
                <td><input type="text" name="id"></td>
            </tr>
            <tr>
                <td>name:</td>
                <td><input type="text" name="name"></td>
            </tr>
            <tr>
                <td>email:</td>
                <td><input type="text" name="email"></td>
            </tr>
            <tr>
                <td>age:</td>
                <td><input type="text" name="age"></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit" name="注册学生"></td>
            </tr>
        </table>
    </form>

</body>
</html>

result.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
result.jsp 注册成功!
</body>
</html>

定义 RegisterServlet(重要代码)

package com.powernode.controller;

import com.powernode.domain.Student;
import com.powernode.service.StudentService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class RegisterServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String strId=request.getParameter("id");
        String strName=request.getParameter("name");
        String strEmail=request.getParameter("email");
        String strAge=request.getParameter("age");

        //创建Sprig容器对象
        String config="applicationContext.xml";
        ApplicationContext ctx=new ClassPathXmlApplicationContext(config);

        System.out.println("容器对象的信息======"+ctx);

        //获取service
        StudentService service= (StudentService) ctx.getBean("studentService");
        Student student=new Student();
        student.setId(Integer.parseInt(strId));
        student.setName(strName);
        student.setAge(Integer.valueOf(strAge));
        student.setEmail(strEmail);
        service.addStudent(student);

        request.getRequestDispatcher("/result.jsp").forward(request,response);

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }
}

这个时候整个项目就可以运行了!

结果分析

当表单提交,跳转到 success.jsp 后,多刷新几次页面,查看后台输出,发现每刷新一次页面,就 new 出一个新的 Spring 容器。即,每提交一次请求,就会创建一个新的 Spring 容器。对于一个应用来说,只需要一个 Spring 容器即可。所以,将 Spring 容器的创建语句放在 ServletdoGet()doPost()方法中是有问题的

此时,可以考虑,将 Spring 容器的创建放在 Servlet 进行初始化时进行,即执行 init()方法时执行。并且,Servlet 还是单例多线程的,即一个业务只有一个 Servlet 实例,所有执行该业务的用户执行的都是这一个 Servlet 实例。这样,Spring 容器就具有了唯一性了。

但是,Servlet 是一个业务一个 Servlet 实例,即 LoginServlet 只有一个,但还会有StudentServletTeacherServlet 等。每个业务都会有一个 Servlet,都会执行自己的 init()方法,也就都会创建一个 Spring 容器了。这样一来,Spring 容器就又不唯一了。

使用 Spring 的监听器 ContextLoaderListener(核心)

对于 Web 应用来说,ServletContext 对象是唯一的,一个 Web 应用,只有一个ServletContext 对象,该对象是在 Web 应用装载时初始化的。若将 Spring 容器的创建时机,放在 ServletContext 初始化时,就可以保证 Spring 容器的创建只会执行一次,也就保证了Spring 容器在整个应用中的唯一性。

当 Spring 容器创建好后,在整个应用的生命周期过程中,Spring 容器应该是随时可以被访问的。即,Spring 容器应具有全局性。而放入 ServletContext 对象的属性,就具有应用的全局性。所以,将创建好的 Spring 容器,以属性的形式放入到 ServletContext 的空间中,就保证了 Spring 容器的全局性。

这些内容都被封装好了,我们只需要在pom文件中加入spring-web依赖就行了

使用监听器 当全局作用域对象被创建时 创建容器 存入ServletContext

添加依赖:

<!--为了使用监听器对象,加入依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>
  </dependencies>

监听器作用:

  1. 创建容器对象,执行 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  2. 把容器对象放入到ServletContextServletContext.setAttribute(key,ctx)

注册监听器 ContextLoaderListener, 在web.xm中加入:

	<!--注册监听器 ContextLoaderListener
        监听器被创建对象后,会读取/WEB-INF/applicationContext.xml
        为什么要读取文件:因为在监听器中要创建ApplicationContext对象,需要加载配置文件。
        /WEB-INF/applicationContext.xml就是监听器默认读取的spring配置文件路径

        可以修改默认的文件位置,使用context-param重新指定文件的位置
    -->
	<context-param>
        <!--contextConfigLocation:表示配置文件的路径-->
        <param-name>contextConfigLocation</param-name>
        <!--自定义配置文件路径-->
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

有两种创建方式:
1.获取ServletContext中的容器对象,容器创建好的,拿来就用

WebApplicationContext ctx=null;
String key=WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE;
Object attr=getServletContext().getAttribute(key);
if(attr!=null)
    ctx=(WebApplicationContext)attr;

2.使用框架里的方法,获取对象(使用定义好的WebApplicationContextUtils工具类)

WebApplicationContext ctx=null;
ServletContext sc=getServletContext();
ctx= WebApplicationContextUtils.getWebApplicationContext(sc);

效果一样,第二种方法实际上就是spring框架帮我们做了(1)中的事情。

以上两种方式,无论使用哪种获取容器对象,刷新 success 页面后,可看到代码中使用的 Spring 容器均为同一个对象。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值