写点什么

推荐学 java——Spring 与 web 项目

作者:逆锋起笔
  • 2022 年 2 月 08 日
  • 本文字数:8490 字

    阅读完需:约 28 分钟

推荐学java——Spring与web项目

关于本文

Spring 的内容已经学习了三篇内容,今天算是最后一篇文章,这节内容基本上是熟悉流程,本文要实现的功能:通过 web 页面访问数据库,实现对数据表中的数据插入和查询;与之前内容不同的是这次要创建 web 项目,而不再是 Java 项目,此外还要简单回顾一下 jsp 的内容,接触到的新知识:如何将 Spring 容器对象全局唯一

实现步骤

第一步:建表

这一步我们还是继续使用上一节内容中新建的表programmer,里面有三个字段:idnameage,很简单,这里不做具体流程展示了。

第二步:创建 web 项目并添加依赖

创建 web 项目其实和创建 java 项目的区别就是我们选择的模板不同,当然还是基于 maven 来创建的,模板选择xxx-maven-archetype-webapp就 ok 了。


创建完成之后,目录结构会比 Java 项目多出来一个webapp目录,相应的缺少了javaresources目录,我们手动创建即可。


pom.xml文件中添加依赖,不同于上节内容的是,这里需要再增加两个依赖(jsp 和 servlet),完整代码如下:


<?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.javafirst</groupId> <artifactId>spring-webapp</artifactId> <version>1.0-SNAPSHOT</version> <packaging>war</packaging>
<!-- <name>spring-webapp Maven Webapp</name>--> <!-- &lt;!&ndash; FIXME change it to the project's website &ndash;&gt;--> <!-- <url>http://www.example.com</url>-->
<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> </properties>
<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency>
<!--MyBatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency>
<!-- Spring依赖 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.14</version> </dependency>
<!-- MyBatis集成Spring --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.3</version> </dependency>
<!-- Spring事务--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>5.3.14</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.14</version> </dependency>
<!-- AspectJ aop实现注解 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.14</version> </dependency>
<!-- 阿里数据库连接池 druid --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.8</version> </dependency>
<!-- servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <!-- jsp --> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.3</version> </dependency> </dependencies>
<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>false</filtering> </resource> </resources> </build>
</project>
复制代码


本文在后面还会增加一个依赖,各位记得这个文件。

第三步:新建 java 实体类

这里新建的实体类中的字段没有和表中字段名保持一致,就这点区别,具体代码如下:


public class Programmer {
private Integer pId; private Integer pAge; private String pName;
public Integer getpId() { return pId; }
public void setpId(Integer pId) { this.pId = pId; }
public Integer getpAge() { return pAge; }
public void setpAge(Integer pAge) { this.pAge = pAge; }
public String getpName() { return pName; }
public void setpName(String pName) { this.pName = pName; }
@Override public String toString() { return "Programmer信息:{" + "pId=" + pId + ", pAge=" + pAge + ", pName='" + pName + '\'' + '}'; }}
复制代码

第四步:创建 dao 和 mapper 文件

我们要实现插入数据和查询数据,所以我们的 dao 只需提供两个接口即可。


public interface ProgrammerDaoNew {
int insertProgrammer(Programmer programmer);
Programmer selectProgrammerById(Integer id);}
复制代码


对应 mapper 文件这里依旧是分开的,位置的resources目录下的mapper文件夹中,具体代码如下:


<?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="com.javafirst.dao.ProgrammerDaoNew">
<insert id="insertProgrammer"> insert into programmer(`name`,age) values (#{pName},#{pAge}) </insert>
<select id="selectProgrammerById" resultMap="selectMap"> select * from programmer where id = #{id} </select>
<resultMap id="selectMap" type="com.javafirst.domain.Programmer"> <id column="id" property="pId"/> <id column="name" property="pName"/> <id column="age" property="pAge"/> </resultMap>
</mapper>
复制代码

第五步:配置 MyBatis 核心文件

这个和上一节内容一样,该配置文件中要完善的内容也大致相同,其实就和前面说过一样,基本上都是流程代码:


<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>        <typeAliases>        <typeAlias type="com.javafirst.domain.Programmer"/>    </typeAliases>
<mappers> <mapper resource="mapper/ProgrammerDaoMapper.xml"/> </mappers></configuration>
复制代码


到这里大家应该有一个感受点吧:


以上流程基本上都是环环相扣的,也就是存在顺序,你看每一个文件中都会引入上一步创建的内容,写多了,自然就顺手了。

第六步:创建业务层 service

我们的业务只有添加记录和查询记录,当然各位还可以在此基础上进行扩展,我们的接口内容如下:


public interface ProgrammerService {
int addProgrammer(Programmer programmer);
Programmer findProgrammer(Integer id);}
复制代码


其实现类中,是我们真实业务开发中需要做的工作,比较各种校验通过后才进行真正的添加记录工作等等。


public class ProgrammerServiceImpl implements ProgrammerService {
ProgrammerDaoNew programmerDao;
public void setProgrammerDao(ProgrammerDaoNew programmerDao) { this.programmerDao = programmerDao; }
@Override public int addProgrammer(Programmer programmer) { return programmerDao.insertProgrammer(programmer); }
@Override public Programmer findProgrammer(Integer id) { return programmerDao.selectProgrammerById(id); }
}
复制代码


有人可能会好奇,这里的 setProgrammerDao() 方法什么时候会调用呢?其实这是 Spring 框架在处理,当我们在 Spring 的配置文件中声明了自定义的 Service 之后,就会自动进行设值注入,这是我们学习Spring第一节内容时掌握的知识。

第七步:配置 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"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!-- 使用属性文件 配置数据源中数据库链接信息 --> <context:property-placeholder location="jdbc.properties"/>
<!-- 声明数据源--> <bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean>
<!-- 声明 SQLSessionFactoryBean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="myDataSource"/> <property name="configLocation" value="classpath:mybatis-config.xml"/> </bean>
<!-- 声明 MapperScannerConfigurer --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
<property name="basePackage" value="com.javafirst.dao"/> </bean>
<bean id="programmerService" class="com.javafirst.service.ProgrammerServiceImpl"> <property name="programmerDao" ref="programmerDaoNew"/> </bean></beans>
复制代码


这里我习惯将数据源的相关配置单独提取文件,这也是主流做法,推荐大家也养成习惯,jdbc.properties文件内容如下:


jdbc.url=jdbc:mysql://localhost:3306/spring_demojdbc.username=rootjdbc.password=root
复制代码


到这里其实我们已经完成了基本的配置,但我们创建的是 web 项目,不是 java 项目,所以我们要进行测试的话,还需要有 web 页面和简单的逻辑,这就要用到我们的webapp目录了以及jsp知识。

第八步:创建 Jsp 页面

我们需要两个 jsp 页面,一个用来录入信息和提供查询功能,也就是插入操作,页面我们提供姓名和年龄输入,然后提交就进行数据库的插入操作,这个文件名就叫register.jsp,其代码如下:


<%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title>录入一个工程师</title></head><body><form method="post" action="add">    <%--  这里的 name 值就是 servlet 中取值的key  --%>    姓名:<input type="text" name="name"><br>    年龄:<input type="text" name="age"><br>    <input type="submit" value="录入"/></form>
<br><br><form method="get" action="find"> 查询工程师信息:<input type="text" name="pId"> <input type="submit" value="查询"></form>
</body></html>
复制代码


这个页面运行起来大概长这样:



当我们录入成功后,页面会跳转到一个成功页面,就是我们的第二个 jsp 页面registerSuccess.jsp,我们不关联具体逻辑,只做简单展示,完整代码如下:


<%--  Created by studyingJava  Date: 2022/1/24  Time: 15:46--%><%@ page contentType="text/html;charset=UTF-8" language="java" %><html><head>    <title>注册成功</title></head><body>    恭喜你,完成注册!即将为您跳转首页...</body></html>
复制代码


查询成功我们不做跳转页面,当前页面也不做展示,我们可以通过控制台看查询信息即可,因为我们在前面的实体类中已经重写了toString() 方法;当然各位如果感兴趣,可以自行将结果显示在页面上。

第九步:创建 Servlet

页面的请求处理和展示我们同样需要创建两个 Servlet,一个用来处理录入请求,也就是 post 提价过来的数据,另一个处理查询操作,也就是 get 请求数据操作,下面是代码:


AddProgrammerServlet.java代码如下:


/** * desc: * author: 推荐学java * <p> * weChat: studyingJava */public class AddProgrammerServlet extends HttpServlet {
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8");
// 取出表单提交过来的注册数据 String name = req.getParameter("name"); String age = req.getParameter("age");
System.out.println("提交过来的数据:" + name + age);
// 创建Spring容器 插入数据库 String config = "spring-applicationContext.xml"; ApplicationContext context = new ClassPathXmlApplicationContext(config);
ProgrammerService service = (ProgrammerService) context.getBean("programmerService");
Programmer programmer = new Programmer(); programmer.setpName(name); programmer.setpAge(Integer.valueOf(age));
service.addProgrammer(programmer);
// 给用户反馈 req.getRequestDispatcher("/registerSuccess.jsp").forward(req, resp); }
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { super.doGet(req, resp); }
}
复制代码


其实这里主要就是三步骤,大家可以看代码注释。


FindProgrammerServlet.java代码如下:


/** * desc: * author: 推荐学java * <p> * weChat: studyingJava */public class FindProgrammerServlet extends HttpServlet {
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { }
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("utf-8");
// 取出表单提交过来的注册数据 String pId = req.getParameter("pId");
System.out.println("提交过来的要查询的用户ID:" + pId);
// 创建Spring容器 插入数据库 String config = "spring-applicationContext.xml"; ApplicationContext context = new ClassPathXmlApplicationContext(config);
ProgrammerService service = (ProgrammerService) context.getBean("programmerService");
Programmer programmer = service.findProgrammer(Integer.valueOf(pId)); System.out.println(programmer); }
}
复制代码


逻辑其实比较简单,细心的朋友是不是发现,我们分别在不同的 Servlet 中创建了 Spring 容器对象,这就是本文开头提出的需要解决的问题,继续往下看。

第十步:配置 Servlet

我们已经创建好了 Servlet,现在进行配置,也就是让浏览器访问的时候能找到对应处理请求的功能承载页面,配置也比较简单,在webapp 目录下的WEB-INF下的 web.xml中完善内容如下:


<!DOCTYPE web-app PUBLIC        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"        "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app> <display-name>Archetype Created Web Application</display-name>
<servlet> <servlet-name>AddProgrammerServlet</servlet-name> <servlet-class>com.javafirst.controller.AddProgrammerServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>AddProgrammerServlet</servlet-name> <url-pattern>/add</url-pattern> </servlet-mapping>
<servlet> <servlet-name>FindProgrammerServlet</servlet-name> <servlet-class>com.javafirst.controller.FindProgrammerServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>FindProgrammerServlet</servlet-name> <url-pattern>/find</url-pattern> </servlet-mapping></web-app>
复制代码


这里就是相当于入口,我们的 Servlet 就相当于页面,而每个页面要使用,就得现在这里注册。

第十一步:发布并测试

到这里,我们的所有工作都已就绪,但不同于 java 项目的是,web 项目需要部署发布才可在浏览器进行访问,关于 IDEA 部署 web 项目,这里就不多讲了,注意一点是你必须安装并配置好 JDKtomcat环境


另外有可能会遇到 8080 端口被占用的错误提示,导致我们的项目 Service 启动不起来,这里给大家一个命令查找某个端口被哪个 PID(进程 ID)占用?


netstat -aon | findstr 8080
复制代码


找出该进程的 ID,然后再通过命令将其 kill 掉:


netstat -aon | findstr 14321
复制代码


然后尝试重新启动项目即可。这里的两条命令是通过命令行窗口执行的。

使用 ContextLoaderListener

这就是我们需要解决前面提到的问题,使用ContextLoaderListener监听器,该监听器是 Spring 框架提供的,核心操作两步:


  • pom.xml中添加依赖spring-web

  • 在 web.xml 中配置context-param标签


spring-web 依赖


<!--    spring-web    --><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-web</artifactId>    <version>1.2.6</version></dependency>
复制代码


web.xml中的配置如下:


<!--  配置 ContextLoaderListener  --><context-param>    <param-name>contextConfigLocation</param-name>    <param-value>classpath:spring-applicationContext.xml</param-value></context-param><listener>    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener>
复制代码


完成这两步配置后,接下来我们就可以使用 Spring 提供的工具类来修改我们的初始化 Spring 容器代码,具体如下:


//String config = "spring-applicationContext.xml";//ApplicationContext context = new ClassPathXmlApplicationContext(config);
// 使用这句就替代了我们前面的使用方式ApplicationContext context = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
复制代码


这样这样在多个地方获取ApplicationContext对象,系统就不会重新创建,保证全局唯一。

总结

  • Spring 与 MyBatis 结合使用其实非常方便,很多工作都可以配置好之后专注业务开发即可这可能就是框架带来的好处

  • 创建基于 maven 的 Java 项目和 web 项目流程必须会,能完善常用配置


学编程,推荐首选 Java 语言,小编创建了一个专注 Java 的原创公众号推荐学java,各位可以在微信搜索javaFirst 关注,一起开启 Java 旅途!

发布于: 刚刚阅读数: 2
用户头像

逆锋起笔

关注

公众号「逆锋起笔」主理人 2018.07.31 加入

程序视角,转射人生!

评论

发布
暂无评论
推荐学java——Spring与web项目