SpringMVC_one

Spring集成web开发环境

使用Maven的webapp模板

①pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.itheima</groupId>
    <artifactId>itheima_springMVC_01</artifactId>
    <version>1.0-SNAPSHOT</version>
    <!--解决java版本错误-->
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
        <java.version>11</java.version>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    
    <!--spring基本包-->
    <dependencies>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>

        <!--servlet基本包-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

        <!--jsp基本包-->
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.2.1</version>
            <scope>provided</scope>
        </dependency>
        
        <!--MySQL驱动包-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.32</version>
        </dependency>
        
        <!--c3p0数据库驱动包-->
        <dependency>
            <groupId>c3p0</groupId>
            <artifactId>c3p0</artifactId>
            <version>0.9.1.2</version>
        </dependency>
        
        <!--druid数据库驱动包-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>
        
        <!--Junit基本包-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        
        <!--Spring集成Junit-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <!--web-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <!--webmvc-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.0.5.RELEASE</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-databind</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.0</version>
        </dependency>
        <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.3</version>
        </dependency>
        
        <!--jdbc模板-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.2.4.RELEASE</version>
        </dependency>
        
        <!--事务管理-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>5.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>
        
        <!--普通单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
</project>
②applicationContext.xml
    <!--配置userDao-->
    <bean id="userDao" class="com.itheima.dao.Impl.UserDaoIpml"></bean>

    <!--配置UserService-->
    <bean id="userService" class="com.itheima.service.Impl.UserServiceIpml">
        <property name="dao" ref="userDao"/>
    </bean>
③Dao
public class UserDaoIpml implements UserDao {

    public void save() {
        System.out.println("save running.....");
    }

}
④Service
public class UserServiceIpml implements UserService {
    private UserDao dao;    //将依赖作为成员变量
    
    public void setDao(UserDao dao) {   //定义set方法
        this.dao = dao;
    }
    //调用dao
    public void save() {
        dao.save();
    }
}
⑤Servlet
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1、加载配置文件,获取容器对象
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2、从容器中获取对象
        UserService service = (UserService) app.getBean("userService");
        //3、执行service
        service.save();
    }
}
⑥web.xml

在SpringMVC中Controller替代了原始的Servlet

    <!--配置servlet名字和绑定类-->
    <servlet>
        <servlet-name>UserServlet</servlet-name>
        <servlet-class>com.itheima.web.UserServlet</servlet-class>
    </servlet>
    <!--配置servlet访问路径-->
    <servlet-mapping>
        <servlet-name>UserServlet</servlet-name>
        <url-pattern>/userServlet</url-pattern>
    </servlet-mapping>

在这里插入图片描述

Spring集成web开发环境:弊端【了解】

在这里插入图片描述

		//1、加载配置文件,获取容器对象
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2、从容器中获取对象
        UserService service = (UserService) app.getBean("userService");
        //3、执行service
        service.save();

从servlet代码中,我们发现我们每次要执行1个doGet/doPost方法都要加载Spring配置文件,创建Spring容器才能使用应用上下文获取对象。但是我们一般web项目开发中,是有很多servlet的,这就意味着我们要多次要加载文件和多次创建Spring容器,这样是不是很多此一举又影响性能?

那么应该怎么解决呢?

首先,实现ServletContextListener接口成为监听器,并且监听事件的创建(web应用启动),当web应用一启动,监听器就会加载Spring配置文件,创建ApplicationContext对象并将其存储到ServletContext容器中供给所有服务器资源共享。(ServletContext是唯一容器(域对象),我要用我就拿就行了,不用自己加载文件再创建容器获取Bean对象)
什么是ServletContext?

Spring集成web开发环境:实现监听器【了解】

在上班原有的基础上做出改变

1、ContextLoadListener类

contextInitialized方法是在web应用一启动就执行

public class ContextLoadListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //1、加载Spring核心加载文件,创建容器对象(applicationContext)
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
       
        //2、获取ServletContext 对象域
        ServletContext servletContext = sce.getServletContext();
        
        //3、将Spirng容器对象存储 到 ServletContext容器中(对象域)
        servletContext.setAttribute("app",app);

        System.out.println("Spring容器创建成功。。。。");
    }
}

2、web.xml配置监听器

【web应用一启动就将spring容器存储到ServletContext】

 <!-- 配置监听器 -->

  <listener>
    <listener-class>com.itheima.listener.ContextLoadListener</listener-class>
  </listener>
3、UserServlet
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、从Servlet对象域中获取容器对象
       ServletContext servletContext = request.getServletContext();//获取对象域
       //ApplicationContext app = (ApplicationContext) servletContext.getAttribute("app");     【方法1】

        ApplicationContext app = (ApplicationContext) this.getServletContext().getAttribute("app"); //【方法2】

        //2、从容器中获取对象
//        UserService service = (UserService) app.getBean("userDao");  【方法1】
        UserService service = app.getBean(UserService.class);        //【方法2】
        //3、执行service
        service.save();
    }
}

输出:

Spring容器创建成功。。。。
save running.....

Spring集成web开发环境:优化监听器【了解】

(在上边代码基础上进行修改)
在以上代码中,我们有2个地方需要优化:

1、在ContextLoadListener类中加载配置文件,配置文件是通过写死的字符串进行获取。

假设如果我们不使用applicationContext.xml了,我们还得修改源代码,这样就耦合了。

//1、加载Spring核心加载文件,创建容器对象(applicationContext)
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");

2、UserServlet中通过开发者指定的app名称获取ServletContext对象域中的Spring容器

app这个名字,是你自己命名并想通过它来获取Spring容器,但是当别人来使用你的代码的时候,别人可能就不知道了。因为别人可能习惯不是取这个名字。

 ApplicationContext app = (ApplicationContext) this.getServletContext().getAttribute("app"); 
解决:
问题①

我要在web.xml中配置全局参数,指定1个名字跟需要加载的配置文件进行绑定;
在加载配置文件的时候,我们获取ServletContext对象域,通过此并获取全局参数
,返回的字符串就是名称,映射的就是配置文件。

web.xml

【自定义名称与配置文件绑定,使用自定义名称就等于使用了该配置文件-】

<!--全局初始化参数-->
  <context-param>
    <param-name>contextConfigLocation</param-name>	【自定义名称】
    <param-value>applicationContext.xml</param-value>	【绑定配置文件】
  </context-param>



,tomcat在启动项目的时候,通过ContextLoaderListener监听器和DispatcherServlet分别初始化了service层的bean和controller层的bean。

ContextLoadListener

public class ContextLoadListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        //1、获取ServletContext对象域
        ServletContext servletContext = sce.getServletContext();
        //2、读取web.xml中的全局参数
        String contextConfigLocation = servletContext.getInitParameter("contextConfigLocation");

        //3、加载Spring核心加载文件,创建容器对象(applicationContext)
        ApplicationContext app = new ClassPathXmlApplicationContext(contextConfigLocation);

        //4、将Spirng容器对象存储 到 ServletContext容器中(对象域)
        servletContext.setAttribute("app",app);

        System.out.println("Spring容器创建成功。。。。");
    }
}

问题②

首先,创建1个工具类。
在使用ServletContext对象域获取ApplicationContext对象时,我们只需要传入ServletContext对象域,调用这个工具类的方法即可返回容器对象。使用者,无需知道存储在ServletContext中ApplicationContext的Key,也可以获取。

WebApplicationContextUtils

public class WebApplicationContextUtils {

    //定义通过ServletContext对象域 获取 ApplicationContext对象
    public static ApplicationContext getWebApplicationContext(ServletContext sc){
        return (ApplicationContext) sc.getAttribute("app");
    }
}

UserServlet

public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
        //1、获取ServletContext对象域
       ServletContext servletContext = request.getServletContext();//获取对象域
//        ApplicationContext app = (ApplicationContext) this.getServletContext().getAttribute("app");

        //2、通过ServletContext对象域 获取 ApplicationContext对象
        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);

        //3、从容器中获取对象
        UserService service = app.getBean(UserService.class);
        //4、执行service
        service.save();
    }
}

Spring工具:集成web开发环境

在这里插入图片描述
意思是说,上面的优化,Spring已经给我们封装好了,我们配置直接用就行了。

①pom.xml如何配置
    <!--web-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
④如何配置web.xml
<!--全局初始化参数-->
  <context-param>
    <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>
③如何Servlet获取Spring容器里的对象
public class UserServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1、获取ServletContext对象域
       ServletContext servletContext = request.getServletContext();//获取对象域
        //2、获取ApplicationContext容器
        //WebApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);  【WebApplicationContext】是ApplicationContext子类
        ApplicationContext app = WebApplicationContextUtils.getWebApplicationContext(servletContext);
        //3、从容器中获取对象
        UserService service = app.getBean(UserService.class);
        //4、执行service
        service.save();
    }

SpringMVC:代码演示

SpringMVC框架将Servlet相同而重复的代码进行了封装。这就意味着,我们不需要在web.xml中配置servlet了,我们配置前端控制器,使用访问前端控制器,其他业务逻辑的代码交由给自定义的controller,这个controller的数据是先被前端控制拦截处理过的。【前端控制器调用controller,也就是说访问资源时,访问的是前端控制器,前端控制再调用指定的POJO】
(POJO指普通的java类(controller))
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

①pom.xml导入SpringMVC包
    <!--Spring-mvc-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.0.5.RELEASE</version>
    </dependency>
②创建spring-mvc.xml:配置controller组件扫描
  • 记得配context命名空间
  • 为什么要提取spring-mvc.xml另外扫描Controller?

spring-mvc扫web层的,spring扫其他的。各扫各的,这是习惯,

    <!--Controller组件扫描:让Spring去指定类扫描注解-->
    <context:component-scan base-package="com.itheima.controller"/>

 
③web.xml

1、配置Servlet
2、配置Cotroller
3、加载spring-mvc配置文件

  <!--配置SpringMVC前端控制器:共有Servlet-->
  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
       <!--当Servlet初始化时,就加载spring-mvc.xml文件-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup><!--服务器一启动就创建serclet-->
  </servlet>
  
  <!--配置前端控制器和url的映射关系-->
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>	<!--包括静态资源,所有的请求都找前端控制器(记得在springmvc开放资源)-->
  </servlet-mapping>


注意:::
 如果在web.xml中servlet-mapping的url-pattern设置的是/。
 表示将所有的文件,包含静态资源文件都交给spring mvc处理。就需要用到<mvc:annotation-driven />了(springmvc.xml配置)。如果不加,DispatcherServlet则无法区分请求是资源文件还是mvc的注解,而导致controller的请求报404错误。
④Controller
@Controller     //告诉Spring帮我实例化Bean

public class UserController {
    @RequestMapping("/quick")           //请求映射:请求xxx/quick时,访问此方法
    public String save(){
        System.out.println("Controller save....");
        return "sucess.jsp";    //返回页面
    }
}

SpringMVC:流程介绍

controller通过return响应页面。
绿色区域是共有的控制器(SpringMVC前端控制器)。
在这里插入图片描述

SpringMVC:组件解析之执行流程

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

SpringMVC:组件解析之注解解析

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

如果在类上添加("/xxx")必须在return的页面前添加“/”.
不然,当你访问这个方法并返回页面时,会404提示—提示/xxx/succes.jsp不存在。因为return succes.jsp的访问路径是相对于这个方法的访问路径的,你加了"/"它才会去wepapp目录下去寻找资源。

SpringMVC:组件解析之注解解析2

在这里插入图片描述
我们一般是这样写

    <!--Controller组件扫描:让Spring去指定类扫描注解-->
    <context:component-scan base-package="com.itheima.controller"/>

也有这样写

只扫org.springframework.stereotype.Controller的注解(这个是Controller注解的全限定名)

    <context:component-scan base-package="com.itheima"> 
        <context:exclude-filter type="aspectj" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

只扫 除开org.springframework.stereotype.Controller的注解

    <context:component-scan base-package="com.itheima"> 
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>	
    </context:component-scan>

SpringMVC:组件解析3

SpringMVC除了扫描组件,其实还有很多组件。
这里只介绍1个类的部分。
在这里插入图片描述
在这里插入图片描述

代码演示
重定向与转发

在这里插入图片描述

视图名称前缀和后缀

假设场景
在这里插入图片描述
如果是上述这样的话,那么我们每次写方法返回都要写这么长,太烦了。

怎么解决?

  • Spring-mvc.xml:
    在这里插入图片描述
  • UserController
    在这里插入图片描述

视图解析器可以配置页面路径的前后缀,如果你配置添加了路径它会对ModelAndView返回的页面和return “ xxx “ 进行自动添加前后缀,但是对于方法的指定跳转方式的返回值是不会自动添加的。
return “跳转方式+/xxx.jsp”

补充:return “xxx”,默认是转发跳转,但是不指定是转发或者重定向都会自动加前后缀的。
在这里插入图片描述

总结

在这里插入图片描述

SpringMVC 是一个基于Java的MVC框架,MyBatis 是一种持久化框架,它们常常一起使用来开发Web应用程序。下面是一个简单的SpringMVC结合MyBatis的selectOne代码例子: 1. 首先,在SpringMVC的配置文件中配置MyBatis的数据源和映射文件。 ```xml <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mydb" /> <property name="username" value="root" /> <property name="password" value="password" /> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="mapperLocations" value="classpath*:mapper/*.xml" /> </bean> <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> <constructor-arg ref="sqlSessionFactory" /> </bean> ``` 2. 然后,创建一个数据访问对象(DAO)接口。 ```java public interface UserMapper { User selectOne(int id); } ``` 3. 接着,创建一个映射文件 UserMapper.xml。 ```xml <mapper namespace="com.example.dao.UserMapper"> <select id="selectOne" resultType="com.example.model.User"> SELECT * FROM users WHERE id = #{id} </select> </mapper> ``` 4. 最后,在控制器中使用该数据访问对象进行数据查询。 ```java @Controller public class UserController { @Autowired private UserMapper userMapper; @RequestMapping("/user/{id}") public String getUser(@PathVariable("id") int id, Model model) { User user = userMapper.selectOne(id); model.addAttribute("user", user); return "user"; } } ``` 以上代码例子演示了SpringMVC结合MyBatis进行数据库查询的过程,通过配置数据源、创建数据访问对象接口和映射文件,并在控制器中调用数据访问对象来实现查询功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值