一、使用servlet开发用户登录功能(用于与后面对比使用Spring的不同)
1、创建dynamic web project,导入基本包
2、拖入准备好的静态资源
这里有一个点要注意噢,一开始我不注意,把静态资源放进了WEB-INF中,因为这是eclipse,对于WEB-INF中的资源有保护作用,所以一直运行时会出现错误--服务器404,把文件拖出来就好了,我一直在找是不是我java代码写错了,真是无奈啊。。。
3、新建包
1)新建数据库、user表,对应bean层实体类
public class User {
private Integer u_id;
private String u_username;
private String u_password;
}
2)dao层:UserDao接口以及其实现类(配置数据库和数据库操作)
public interface UserDao {
User getUserByInfo(User user);
}
public class UserDaoImpl implements UserDao{
private static ComboPooledDataSource dataSource;
static {
try {
//配置c3p0数据库
dataSource = new ComboPooledDataSource();
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ssm_spring");
dataSource.setUser("root");
dataSource.setPassword("root");
} catch (PropertyVetoException e) {
e.printStackTrace();
}
}
@Override
//通过数据库查询用户
public User getUserByInfo(User user) {
try {
//使用dbutil操作数据库,查询并返回对象
QueryRunner qRunner = new QueryRunner(dataSource);
String sql = "select * from user where u_username=? and u_password=?";
return qRunner.query(sql,new BeanHandler<User>(User.class), user.getU_username(),user.getU_password());
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
3)Service层:UserService 接口以及其实现类
public interface UserService {
//通过用户信息获取用户
public User getUserByInfo(User user);
}
public class UserServiceImpl implements UserService {
private UserDao ud = new UserDaoImpl();
@Override
public User getUserByInfo(User user) {
return ud.getUserByInfo(user);
}
}
4)web层(类似于Controller,放servlet)
@WebServlet("/userLogin")
public class userLogin extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//接收表单数据
String username = request.getParameter("username");
String password = request.getParameter("password");
//封装成user对象
User user = new User();
user.setU_username(username);
user.setU_password(password);
//调用service验证用户
UserService us = new UserServiceImpl();
User loginUser = us.getUserByInfo(user);
//根据用户验证结果进行操作
if(loginUser == null) {
//验证失败,转发到login_page.jsp
request.setAttribute("errorMsg", "用户名或密码错误");
request.getRequestDispatcher("/login_page.jsp").forward(request, response);
}else {
//验证成功,重定向到index.jsp
HttpSession session = request.getSession();
session.setAttribute("user", loginUser);
response.sendRedirect(request.getContextPath()+"/index.jsp");
}
}
}
5)tomcat 跑起来OK了。
二、使用Spring改造项目
.。。。搞了半天错误,我的数据库居然莫名其妙没了。。。。气死我了。。。。
(1)将原本项目中由自身生成调用的改用spring容器管理
比如:UserDaoImpl中原本的数据库连接、配置全部改由spring容器管理
public class UserDaoImpl implements UserDao{
private ComboPooledDataSource dataSource;
public void setDataSource(ComboPooledDataSource dataSource) {
this.dataSource = dataSource;
}
@Override
//通过数据库查询用户
public User getUserByInfo(User user) {
try {
//使用dbutil操作数据库,查询并返回对象
QueryRunner qRunner = new QueryRunner(dataSource);
String sql = "select * from user where u_username=? and u_password=?";
return qRunner.query(sql,new BeanHandler<User>(User.class), user.getU_username(),user.getU_password());
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
applicationContext.xml中添加:
<!-- 配置dataSource -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm_spring"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
<!-- 配置DAO -->
<bean name="UserDao" class="com.dunka.dao.UserDaoImpl">
<property name="dataSource" ref="dataSource" />
</bean>
还有UserServiceImpl中调用UserDao并生成对象也改由spring直接引用bean对象
public class UserServiceImpl implements UserService {
private UserDao ud;
public void setUd(UserDao ud) {
this.ud = ud;
}
@Override
public User getUserByInfo(User user) {
return ud.getUserByInfo(user);
}
}
applicationContext.xml中
<!-- 配置service -->
<bean name="UserService" class="com.dunka.service.UserServiceImpl">
<property name="ud" ref="UserDao"></property>
</bean>
(2)要明白一点,web项目中使用spring容器的生命周期最好是跟web项目同步,项目开启即生成spring容器,关闭即销毁容器,其生命周期有点像application域,所以在此可以利用servletContext,而spring中提供了一个封装包,spring-web-xxx.jar里面有一个webapplicationContext的工具类,用于监听项目的状况,除了在逻辑层开启监听器,需要在web.xml中配置此监听器,并需要配置读取spring配置文件
UserLogin中添加以下几行代码:
WebApplicationContext wac=WebApplicationContextUtils.getWebApplicationContext(getServletContext());
us=(UserService) wac.getBean("UserService");
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<!-- needed for ContextLoaderListener -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- Bootstraps the root web application context before servlet initialization -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
(如果有spring的集成插件,alt+/ 选择contextConfigLocation 只需在param-value中填入spring配置文件的相对引用路径)
(3)运行测试
三、总结
从servlet中可以知道每个层都是互相调用,用户调用Service,Service调用dao,dao层调用数据库,从这一层面来说,可以将所以关系都用spring的bean对象用以互相调用,降低各层之间的耦合度,统一用spring管理,在项目较大时会特别方便。此项目还涉及到web中的一些生命周期的问题,如第一版本,每次请求其实都会产生一个spring容器,并不是我要的目的,改由监听器控制spring容器的生命周期更能符合我们的要求