简单Spring MVC项目搭建

1.新建Project

开发环境我使用的是IDEA,其实使用什么都是大同小异的,关键是自己用的顺手。

首先,左上角File→New→Project。在Project页面选择Maven,然后勾上图中所示的选项,在下面选择maven-archetype→webapp选项,这个选项是Maven自动帮我们生成一个简单的Web程序,这样可以省去我们的一些工作,不选择这个也是完全可以的,这里为了方便直接勾选了。

接着填写GroupId,ArtifactId以及Version。

接下来这个页面,建议在Properties选项中新增一个选项:archetypeCatalog : internal,这是因为IDEA在执行archetype:generate命令时,需要指定一个archetype-catalog.xml文件,新增的这个选项就是用于指定这个文件从哪里获取的。默认值为remote,下载获取比较慢,我们把值设为internal,可加快速度。

接着一直点到Finish,等待Project构建完成。完成后,我们的项目结构是这个样子。

2. 填写pom.xml文件

  • 首先需要添加的是properties标签中的内容,这个标签中表示的是我们在pom.xml文件中可以引用的,一般情况下,我们可以把要引用的jar包的版本号放在这里,方便以后的修改。比如,我们要使用mysql的版本是5.1.29,就可以在properties标签中添加”

3.按照SpringMVC的包结构将包建好

先在main文件夹下新建java文件夹,然后在java文件夹上右键新建package,这时你的IDEA可能是如图下面这样的,即看不到有新建package这个选项。

这是因为IDEA没有自动识别出你的“java”文件夹下面要放类了,这时可以打开File→Project Structure对话框,找到我们刚刚新建的java文件夹,将其设置为Sources类型,如下图所示。

这下便可以右键新建package了。

我们一共需要建四个包,分别是:com.tryking.dao,com.tryking.domain,com.tryking.service,com.tryking.web。下图是建好后的结构图。

其中,dao是用来存放操作数据库的类的(Data Access Object),domain用于存放实体类,service用于进行真正的业务操作,web用于存放接口的处理。先暂时了解这么多,具体的代码实现我们后面说。

4.配置SpringMVC以及JDBC等的配置文件

SpringMVC可以让我们的开发更加方便,我们需要在用它之前对它进行一些配置,配置文件需要在src→main→resource文件夹下新建,这里我们新建为bbs-context.xml文件。文件内容如下所示,下面进行简要说明。

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd
       http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">

    <!-- 1.扫描类包,将标注Spring注解的类自动转化Bean,同时完成Bean的注入 -->
    <context:component-scan base-package="com.tryking.dao"/>
    <context:component-scan base-package="com.tryking.service"/>

    <!-- 2.配置数据源 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
          destroy-method="close"
          p:driverClassName="com.mysql.jdbc.Driver"
          p:url="jdbc:mysql://localhost:3306/sampledb"
          p:username="root"
          p:password="root"/>

    <!-- 3.配置Jdbc模板  -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"
          p:dataSource-ref="dataSource"/>

    <!-- 4.配置事务管理器 -->
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
          p:dataSource-ref="dataSource"/>

    <!-- 5.通过AOP配置提供事务增强,让service包下所有Bean的所有方法拥有事务 -->
    <aop:config proxy-target-class="true">
        <aop:pointcut id="serviceMethod"
                      expression="(execution(* com.tryking.service..*(..))) and (@annotation(org.springframework.transaction.annotation.Transactional))"/>
        <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/>
    </aop:config>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
</beans>

如上,1用于配置Spring所需的类包地址,也就是说我们需要告诉Spring我们具体不同类型的类的位置在哪里,可以看到,我们这里将dao和service包的地址配置了进去。2用于配置数据源,即用于连接MySQL数据库的内容,可以看到我们这里连接的数据库是sampledb,MySQL的用户名和密码都是root,如果你自己的MySQL端口号,用户名以及密码和上面不符,记得要进行修改。关于数据库的创建我们后面再说。3用于配置JDBC的模板,也就是用于操作数据库的东西,直接copy上去就ok。4用于配置事务管理器,依旧copy。5用于提供事务增强,可以看到,我们将service包配置了进去。具体作用目前可以不用了解,想了解的可以自己百度一下看看。

5.配置servlet文件

上面我们创建的四个包,有三个包都在4中进行配置了,还剩最后一个web包也是需要配置的,这个需要配置到servlet文件中,在WEB-INF文件夹上,右键新建文件,输入“bbs-servlet.xml”,得到下面结构。

在这个文件中,我们填入的内容为:

<?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:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <!-- 扫描web包,应用Spring的注解 -->
    <context:component-scan base-package="com.tryking.web"/>

    <!-- 配置视图解析器,将ModelAndView及字符串解析为具体的页面 -->
    <bean
            class="org.springframework.web.servlet.view.InternalResourceViewResolver"
            p:viewClass="org.springframework.web.servlet.view.JstlView"
            p:prefix="/WEB-INF/jsp/"
            p:suffix=".jsp"/>
</beans>

可以看到,我们将新建的web包也配置进去了,这样可以让Spring识别我们的内容。

6.需求分析,数据库建立

前面我们已经将基本的环境搭建好了,下面就是考虑我们要做什么了,要使用Spring MVC的基本功能,我们需要访问数据库,并且要将数据展现在页面上,这样就可以将我们前面建的4个包都用上了。我们的需求是用户访问第一个页面,有输入用户名密码的输入框,输入登录成功后,展现用户的积分,登录失败则提示用户登录失败。因此首先,我们需要建立一个数据库。

  • 新建数据库

    打开命令行,进入mysql。执行下面的SQL语句新建一个数据库“sampledb”。

    DROP DATABASE IF EXISTS sampledb;
    CREATE DATABASE sampledb DEFAULT CHARACTER SET utf8;
    

    如下图所示。

  • 新建表

    继续执行以下命令,新建一个表t_user,表中含四列:user_id,user_name,password,credits。分别表示用户的id,用户名,密码以及积分。

    ##创建用户表
    CREATE TABLE t_user (
       user_id   INT AUTO_INCREMENT PRIMARY KEY,
       user_name VARCHAR(30),
       password  VARCHAR(32),
       credits INT;
    )ENGINE=InnoDB; 
    

    如下图所示。

  • 添加一条数据

    当然我们还需要添加进去一条数据,以供我们后续操作。操作内容如下。

    ##插入初始化数据
    INSERT INTO t_user (user_name,password) VALUES ('admin','123456');
    

    如下图所示。

这样我们数据库内容的部分就算是完成了。为了检验我们的数据库操作是否正确,我们可以查询检验一下我们表中的数据,如下图所示。

可以看到,我们的数据已经成功添加进去了。后续我们只需要访问数据库对用户名和密码进行验证即可。

7.代码编写

  • domain层代码

    首先,我们把实体类给写出来,根据需求,我们这里只需要一个用户实体就可以了,即我们创建一个User.java,如下图所示。

    具体代码如下:

    package com.tryking.domain;
    
    import java.io.Serializable;
    
    public class User implements Serializable {
        private int userId;
        private String userName;
        private String password;
        private int credits;
    
        public int getUserId() {
            return userId;
        }
    
        public void setUserId(int userId) {
            this.userId = userId;
        }
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    
        public int getCredits() {
            return credits;
        }
    
        public void setCredits(int credits) {
            this.credits = credits;
        }
    }
    

    可以看到,我们的User中只有四个变量,这和我们数据库中的数据是对应的。

  • dao层代码

    接下来是dao层代码的编写,即对数据库的访问。根据需求,我们需要对用户的用户名和密码进行校验,如果正确,则获取用户的积分,并且给它加上5分。如果用户名密码错误,则返回错误即可。由此可得,我们需要写的访问数据库的操作如下代码所示,均有注释,根据注释去理解下就可以。

    package com.tryking.dao;
    
    import com.tryking.domain.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.jdbc.core.JdbcTemplate;
    import org.springframework.jdbc.core.RowCallbackHandler;
    import org.springframework.stereotype.Repository;
    
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    @Repository
    public class UserDao {
        private JdbcTemplate jdbcTemplate;
        private final static String MATCH_COUNT_SQL = "SELECT count(*) FROM t_user WHERE user_name =? and password=?";
        private final static String FIND_USER_SQL = "SELECT user_id,user_name,credits FROM t_user WHERE user_name=?";
        private final static String UPDATE_LOGIN_INFO_SQL = "UPDATE t_user SET credits=? WHERE user_id=?";
    
        //根据用户名和密码获取匹配的数量
        public int getMatchCount(String userName, String password) {
            return jdbcTemplate.queryForObject(MATCH_COUNT_SQL, new Object[]{userName, password}, Integer.class);
        }
    
        //更新用户的信息
        public void updateLoginInfo(User user) {
            jdbcTemplate.update(UPDATE_LOGIN_INFO_SQL, new Object[]{user.getCredits(), user.getUserId()});
        }
    
        //根据用户名找到用户
        public User findUserByUserName(final String userName) {
            final User user = new User();
            jdbcTemplate.query(FIND_USER_SQL, new Object[]{userName}, new RowCallbackHandler() {
                public void processRow(ResultSet resultSet) throws SQLException {
                    user.setUserId(resultSet.getInt("user_id"));
                    user.setUserName(resultSet.getString("user_name"));
                    user.setCredits(resultSet.getInt("credits"));
                }
            });
            return user;
        }
    
        @Autowired
        public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
    }
    

    值得注意的是,代码中有两处注解,这些都是必须的,因为Spring要根据这些信息去找对应的东西。

  • service层代码

    在service层,是我们真正的业务逻辑操作,我们的逻辑就只有三个,第一,判断用户名密码是否正确。第二,根据用户名获取用户。第三,更新用户的信息。因此,代码如下:

    package com.tryking.service;
    
    import com.tryking.dao.UserDao;
    import com.tryking.domain.User;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;
    
    @Service
    public class UserService {
        private UserDao userDao;
    
        //是否有匹配用户
        public boolean hasMatchUser(String userName, String password) {
            int matchCount = userDao.getMatchCount(userName, password);
            return matchCount > 0;
        }
    
        //根据用户名找用户
        public User findUserByUserName(String userName) {
            return userDao.findUserByUserName(userName);
        }
    
        //登录成功,给用户加上5个积分
        @Transactional
        public void loginSuccess(User user) {
            user.setCredits(5 + user.getCredits());
            userDao.updateLoginInfo(user);
        }
    
        @Autowired
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    }
    

    代码中依然有两处注解,这些也都是必须的,因为Spring要根据这些信息去找对应的东西。

  • web层代码

    最后就是web层的代码了,根据需求,我们需要处理的逻辑只有两个,首先是用户访问我们主页的时候,将登陆也展现出来,用户输入完成,验证成功的时候,返回登录成功页面。因此,我们的代码如下,详情看注释。

    package com.tryking.web;
    
    import com.tryking.domain.User;
    import com.tryking.service.UserService;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    
    @RestController
    public class LoginController {
        private UserService userService;
        private Log log = LogFactory.getLog(LoginController.class);
    
        /**
         * 用户访问首页的时候,自动跳转到“login”页面
         *
         * @return login页面
         */
        @RequestMapping(value = "/")
        public String loginPage() {
            log.error("********进入index.html页面***********");
            return "login";
        }
    
        /**
         * @param request request对象
         * @param command 用户输入的用户名、密码对象
         * @return 登录成功页面/失败信息
         */
        @RequestMapping(value = "/loginCheck.html")
        public ModelAndView loginCheck(HttpServletRequest request, LoginCommand command) {
            log.error("********进入loginCheck.html页面***********");
            boolean isValidUser = userService.hasMatchUser(command.getUserName(), command.getPassword());
    
            if (!isValidUser) {
                return new ModelAndView("login", "error", "用户名密码不符");
            } else {
                User user = userService.findUserByUserName(command.getUserName());
                //登录成功,加积分。
                userService.loginSuccess(user);
                request.getSession().setAttribute("user", user);
                return new ModelAndView("main");
            }
        }
    
        @Autowired
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
    }
    

    登录成功后,我们做了用户积分更新的处理。然后我们还需要将user对象用request写回给浏览器,因为我们要将用户信息展现给用户。可以看到,我们程序中还用到了一个LoginCommand对象,这个对象中是保存网页JSP页面中用户给我们传回来的用户名和密码的,JSP与我们程序交互,我们获取到的就是JSP中名称与之相同的对象,因此我们还创建了一个LoginCommand对象,具体如下:

    package com.tryking.web;
    
    public class LoginCommand {
        private String userName;
        private String password;
    
        public String getUserName() {
            return userName;
        }
    
        public void setUserName(String userName) {
            this.userName = userName;
        }
    
        public String getPassword() {
            return password;
        }
    
        public void setPassword(String password) {
            this.password = password;
        }
    }
    

    在JSP页面中,我们用户名输入框的name必须设置为userName,密码输入框的nama必须设置为password,这样程序才可以正常识别。

这样,我们的代码就都编写完成了,最终的程序结构图如下。

8. 页面编写

上面程序都写完了,接下来就是要写用户可以访问的页面了,我们的页面很简单,只需要有一个登录页面,一个登录成功页面即可。我们需要在WEB-INF文件夹下创建一个JSP文件夹,然后新建两个页面:login.jsp以及main.jsp。如下:

首先是登录页面login.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
    <title>bbs论坛登录</title>
</head>
<body>
<form action="<c:url value="loginCheck.html"/>" method="post">
    <br><font color="#4b0082" size="12">欢迎使用bbs论坛</font><br><br>
    用户名:
    <input type="text" name="userName">
    <br>
    <br>
    密&#12288;码:
    <input type="password" name="password">
    <br>
    <br>
    <input type="submit" value="登录"/>
    <input type="reset" value="重置"/>
</form>
<br>
<c:if test="${!empty error}">
    <font color="red" size="5"><c:out value="${error}"/></font>
</c:if>
</body>
</html>

可以看到,我们的用户名,密码输入框的值分别为userName和password,与我们前面loginCommand是对应的。接下来是登录成功展示页面main.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
     pageEncoding="UTF-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>bbs论坛</title>
</head>
<body>
${user.userName},<br><br>欢迎您进入bbs论坛,<br><br>您当前积分为${user.credits}。
<br><br>
<input type="button" value="退出" onClick="javascript:location.href='/bbs'">
</body>
</html>

至此,我们的页面就都写完了。最后,还有一个关键的步骤。

9. web.xml文件配置

最后,我们还需要做一个web.xml文件的配置,配置内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <!--******************Context配置******************-->
        <param-value>classpath:bbs-context.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>

    <servlet>
        <servlet-name>bbs</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        <load-on-startup>3</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>bbs</servlet-name>
        <!-- 设置我们的首页 -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

至此,就大功告成了。我们一起来运行一下,看看我们的程序是否能跑起来。

我们先用Jetty运行,首先打开Maven Projects页面,按照下图所示,鼠标移到左下角的位置点击便Maven Projects页面便可在右上角出现。

接着,我们点开jetty标签,双击jetty:run进行测试。当出现如下图所示的内容时,说明jetty服务器已经跑起来了,我们就可以进行测试了。

打开网页,输入: http://127.0.0.1:8000/bbs/ ,就可以成功看到我们的登录页面了。

我们键入用户名:admin,密码:1234 点击登录,可以看到:

我们键入用户名:admin,密码:12345 点击登录,可以看到:

OK,大功告成,一个简单的Spring MVC项目已经被我们实现了。

博客地址:我是博客传送门

项目源码地址:我是源码传送门

转载于:https://www.cnblogs.com/dengkaiting/p/11069355.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值