开发环境我使用的是IDEA,其实使用什么都是大同小异的,关键是本身用的顺手。javascript
首先,左上角File→New→Project。在Project页面选择Maven,而后勾上图中所示的选项,在下面选择maven-archetype→webapp选项,这个选项是Maven自动帮咱们生成一个简单的Web程序,这样能够省去咱们的一些工做,不选择这个也是彻底能够的,这里为了方便直接勾选了。html
接着填写GroupId,ArtifactId以及Version。java
接下来这个页面,建议在Properties选项中新增一个选项:archetypeCatalog : internal,这是由于IDEA在执行archetype:generate命令时,须要指定一个archetype-catalog.xml文件,新增的这个选项就是用于指定这个文件从哪里获取的。默认值为remote,下载获取比较慢,咱们把值设为internal,可加快速度。mysql
接着一直点到Finish,等待Project构建完成。完成后,咱们的项目结构是这个样子。git
首先须要添加的是properties标签中的内容,这个标签中表示的是咱们在pom.xml文件中能够引用的,通常状况下,咱们能够把要引用的jar包的版本号放在这里,方便之后的修改。好比,咱们要使用mysql的版本是5.1.29,就能够在properties标签中添加”github
先在main文件夹下新建java文件夹,而后在java文件夹上右键新建package,这时你的IDEA多是如图下面这样的,即看不到有新建package这个选项。web
这是由于IDEA没有自动识别出你的“java”文件夹下面要放类了,这时能够打开File→Project Structure对话框,找到咱们刚刚新建的java文件夹,将其设置为Sources类型,以下图所示。spring
这下即可以右键新建package了。sql
咱们一共须要建四个包,分别是:com.tryking.dao,com.tryking.domain,com.tryking.service,com.tryking.web。下图是建好后的结构图。数据库
其中,dao是用来存放操做数据库的类的(Data Access Object),domain用于存放实体类,service用于进行真正的业务操做,web用于存放接口的处理。先暂时了解这么多,具体的代码实现咱们后面说。
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包配置了进去。具体做用目前能够不用了解,想了解的能够本身百度一下看看。
上面咱们建立的四个包,有三个包都在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识别咱们的内容。
前面咱们已经将基本的环境搭建好了,下面就是考虑咱们要作什么了,要使用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');
以下图所示。
这样咱们数据库内容的部分就算是完成了。为了检验咱们的数据库操做是否正确,咱们能够查询检验一下咱们表中的数据,以下图所示。
能够看到,咱们的数据已经成功添加进去了。后续咱们只须要访问数据库对用户名和密码进行验证便可。
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,这样程序才能够正常识别。
这样,咱们的代码就都编写完成了,最终的程序结构图以下。
上面程序都写完了,接下来就是要写用户能够访问的页面了,咱们的页面很简单,只须要有一个登陆页面,一个登陆成功页面便可。咱们须要在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> 密 码: <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>
至此,咱们的页面就都写完了。最后,还有一个关键的步骤。
最后,咱们还须要作一个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项目已经被咱们实现了。
博客地址:我是博客传送门
项目源码地址:我是源码传送门