Servlet+JSP+JavaBean(MVC)

下面是本项目所使用的工具和技术:

工具:Eclipse + MongoChef + Tomcat8

技术: Servlet+JSP+JavaBean + Maven + Mongdb + Gson + JSTL

1 首先搭建web项目,不添加任何依赖(以防出错,便于排查)

1.1 先创建一个Maven项目,记住选择webapp。如下图所示。

1.2 对新创建的web项目做相应修改(如果不存在以下错误或问题,可跳过),如下图所示。

 

1.3 创建一个空的index.jsp

1.4 启动server,访问http://localhost:8080/servlet-jsp-javabean/。如无错误,证明web项目已创建好。

2  Servlet+JSP+JavaBean (MVC ) 开发web应用

Servlet+JSP+JavaBean模式(MVC)适合开发复杂的web应用,在这种模式下,servlet负责处理用户请求,jsp负责数据显示,javabean负责封装数据。 Servlet+JSP+JavaBean模式程序各个模块之间层次清晰,web开发推荐采用此种模式。

2.1 在pom.xml添加jar依赖

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.0.1</version>   
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.1</version>           
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>1.8.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.2</version>
        </dependency>
        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.8.3</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/jstl/jstl -->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
2.2 创建包层次


2.4 分层架构的代码编写

2.4.1 开发entity层

public class User implements Serializable {
	private static final long serialVersionUID = 1L;
	// 用户名
	private String userName;
	// 用户密码
	private String userPwd;
	// 用户邮箱
	private String email;
	// 用户生日
	private Date birthday;
	
	set/get省略
}

2.4.2 开发数据访问层dao

public interface IUserDao {
	
	void add(User user);
	
	User find(String userName, String userPwd);

	User find(String userName);
}
public class UserDaoImpl implements IUserDao {
	
	private DBCollection userdb = MongdbUtil.getDBCollection("user");
	private Gson gson = new Gson();
	
	@Override
	public void add(User user) {
		userdb.save((DBObject) JSON.parse(gson.toJson(user)));// 存入值
	}

	@Override
	public User find(String userName, String userPwd) {
		BasicDBObject query = new BasicDBObject();  
		query.put("userName", userName);
		query.put("userPwd", userPwd);
		DBCursor cursor = userdb.find(query);  
		while (cursor.hasNext()) {
			return gson.fromJson(cursor.next().toString(), User.class);
		}
		return null;
	}

	@Override
	public User find(String userName) {
		BasicDBObject query = new BasicDBObject();  
		query.put("userName", userName);
		DBCursor cursor = userdb.find(query);  
		while (cursor.hasNext()) {
			return gson.fromJson(cursor.next().toString(), User.class);
		}
		return null;
	}
}

2.4.3 开发service层

public interface IUserService {
	void registerUser(User user);
	User loginUser(String userName, String userPwd);
}
public class UserServiceImpl implements IUserService {
	private IUserDao userDao = new UserDaoImpl();

	@Override
	public void registerUser(User user) {
		if (userDao.find(user.getUserName())!=null) {
			System.out.println("用户存在");
		}
		userDao.add(user);
	}

	@Override
	public User loginUser(String userName, String userPwd) {
		return userDao.find(userName, userPwd);
	}
}

2.4.4 开发页面jsp

<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>用户注册</title>
</head>
<body style="text-align: center;">
	<form action="${pageContext.request.contextPath}/register" method="post">
		<table width="60%" border="1">
			<tr>
				<td>用户名</td>
				<td><input type="text" name="userName" value="${registerBean.userName}">${registerBean.errors.userName}</td>
			</tr>
			<tr>
				<td>密码</td>
				<td><input type="password" name="userPwd" value="${registerBean.userPwd}">${registerBean.errors.userPwd}</td>
			</tr>
			<tr>
				<td>确认密码</td>
				<td><input type="password" name="confirmPwd" value="${registerBean.confirmPwd}">${registerBean.errors.confirmPwd}
				</td>
			</tr>
			<tr>
				<td>邮箱</td>
				<td><input type="text" name="email" value="${registerBean.email}">${registerBean.errors.email}
				</td>
			</tr>
			<tr>
				<td>生日</td>
				<td><input type="text" name="birthday" value="${registerBean.birthday}">${registerBean.errors.birthday}</td>
			</tr>
			<tr>
				<td><input type="reset" value="清空"></td>
				<td><input type="submit" value="注册"></td>
			</tr>
		</table>
	</form>
</body>
</html>
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
<head>
<title>用户登陆</title>
</head>
<body>
	<form action="${pageContext.request.contextPath }/login" method="post">
		用户名:<input type="text" name="username"><br /> 
		密码:<input type="password" name="password"><br />
		<input type="submit" value="登陆">
	</form>
</body>
</html>
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>Insert title here</title>
</head>
<body>
${message}
</body>
</html>
<%@ page language="java" pageEncoding="UTF-8"%>
<%--为了避免在jsp页面中出现java代码,这里引入jstl标签库,利用jstl标签库提供的标签来做一些逻辑判断处理 --%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML>
<html>
<head>
<title>首页</title>
<script type="text/javascript">
         function doLogout(){
             //访问LogoutServlet注销当前登录的用户
             window.location.href="${pageContext.request.contextPath}/logout";
         }
     </script>
</head>

<body>
	<h1>Angelia的网站</h1>
	<hr />
	<c:if test="${user==null}">
		<a href="${pageContext.request.contextPath}/registerIndex" target="_blank">注册</a>
		<a href="${pageContext.request.contextPath}/loginIndex">登陆</a>
	</c:if>
	<c:if test="${user!=null}">
             欢迎您:${user.userName}
            <input type="button" value="退出登陆" onclick="doLogout()">
	</c:if>
	<hr />
</body>
</html>

2.4.5 开发bean层

public class RegisterBean {
	private String userName;
	private String userPwd;
	private String confirmPwd;
	private String email;
	private String birthday;

	/**
	 * 存储校验不通过时给用户的错误提示信息
	 */
	private Map<String, String> errors = new HashMap<String, String>();

	public Map<String, String> getErrors() {
		return errors;
	}
	public void setErrors(Map<String, String> errors) {
		this.errors = errors;
	}

	/*
	 * validate方法负责校验表单输入项 表单输入项校验规则:
	 * userName; 用户名不能为空,并且要是4-10的字母 abcdABcd 
	 * userPwd; 密码不能为空,并且要是3-8的数字
	 * confirmPwd; 两次密码要一致 
	 * email; 可以为空,不为空要是一个合法的邮箱 
	 * birthday; 可以为空,不为空时,要是一个合法的日期
	 */
	public boolean validate() {

		boolean isOk = true;

		if (this.userName == null || this.userName.trim().equals("")) {
			isOk = false;
			errors.put("userName", "用户名不能为空!!");
		} else {
			if (!this.userName.matches("[a-zA-Z]{4,10}")) {
				isOk = false;
				errors.put("userName", "用户名必须是4-10位的字母!!");
			}
		}

		if (this.userPwd == null || this.userPwd.trim().equals("")) {
			isOk = false;
			errors.put("userPwd", "密码不能为空!!");
		} else {
			if (!this.userPwd.matches("\\d{3,8}")) {
				isOk = false;
				errors.put("userPwd", "密码必须是3-8位的数字!!");
			}
		}

		// password2; 两次密码要一致
		if (this.confirmPwd != null) {
			if (!this.confirmPwd.equals(this.userPwd)) {
				isOk = false;
				errors.put("confirmPwd", "两次密码不一致!!");
			}
		}

		// email可以为空,不为空要是一个合法的邮箱
		if (this.email != null && !this.email.trim().equals("")) {
			if (!this.email.matches("\\w+@\\w+(\\.\\w+)+")) {
				isOk = false;
				errors.put("email", "邮箱不是一个合法邮箱!!");
			}
		}

		// birthday可以为空,不为空时,要是一个合法的日期
		if (this.birthday != null && !this.birthday.trim().equals("")) {
			try {
				DateLocaleConverter conver = new DateLocaleConverter();
				conver.convert(this.birthday);
			} catch (Exception e) {
				isOk = false;
				errors.put("birthday", "生日必须要是一个日期!!");
			}
		}

		return isOk;
	}

	get/set 省略
}

2.4.6 开发controller,以及配置文件web.xml

public class RegisterIndexServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}
public class RegisterServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.setCharacterEncoding("utf-8");
		response.setCharacterEncoding("utf-8");
		// 将客户端提交的表单数据封装到RegisterBean对象中
		RegisterBean registerBean = WebUtils.request2Bean(request, RegisterBean.class);
		// 校验用户注册填写的表单数据
		if (registerBean.validate() == false) {// 如果校验失败
			// 将封装了用户填写的表单数据的bean对象发送回register.jsp页面的form表单中进行显示
			request.setAttribute("registerBean", registerBean);
			// 校验失败就说明是用户填写的表单数据有问题,那么就跳转回register.jsp
			request.getRequestDispatcher("/WEB-INF/pages/register.jsp").forward(request, response);
			return;
		}

		User user = new User();
		try {
			// 注册字符串到日期的转换器
			ConvertUtils.register(new DateLocaleConverter(), Date.class);
			BeanUtils.copyProperties(registerBean, user);// 把表单的数据填充到JavaBean user中
			IUserService service = new UserServiceImpl();
			// 调用service层提供的注册用户服务实现用户注册
			service.registerUser(user);
			String message = String.format("注册成功!!3秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content='3;url=%s'/>",
							request.getContextPath() + "/loginIndex");
			request.setAttribute("message", message);
			request.getRequestDispatcher("/message.jsp").forward(request, response);

		} catch (Exception e) {
			e.printStackTrace(); // 在后台记录异常
			request.setAttribute("message", "对不起,注册失败!!");
			request.getRequestDispatcher("/message.jsp").forward(request, response);
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}
public class LoginIndexServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		request.getRequestDispatcher("/WEB-INF/pages/login.jsp").forward(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}
}
public class LoginServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		//获取用户填写的登录用户名
		String username = request.getParameter("username");
		//获取用户填写的登录密码
		String password = request.getParameter("password");

		IUserService service = new UserServiceImpl();
		//用户登录
		User user = service.loginUser(username, password);
		if(user==null){
			String message = String.format("对不起,用户名或密码有误!!请重新登录!2秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content='2;url=%s'", 
					request.getContextPath()+"/login");
			request.setAttribute("message",message);
			request.getRequestDispatcher("/message.jsp").forward(request, response);
			return;
		}
		//登录成功后,就将用户存储到session中
		request.getSession().setAttribute("user", user);
		String message = String.format("恭喜:%s,登陆成功!本页将在3秒后跳到首页!!<meta http-equiv='refresh' content='3;url=%s'", 
				user.getUserName(), request.getContextPath()+"/index.jsp");
		request.setAttribute("message",message);
		request.getRequestDispatcher("/message.jsp").forward(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
public class LogoutServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//移除存储在session中的user对象,实现注销功能
		request.getSession().removeAttribute("user");

		String message = String.format(
				"注销成功!!3秒后为您自动跳到登录页面!!<meta http-equiv='refresh' content='3;url=%s'/>", 
				request.getContextPath()+"/loginIndex");
		request.setAttribute("message",message);
		request.getRequestDispatcher("/message.jsp").forward(request, response);
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}
        <servlet>
		<description>This is the description of my J2EE component</description>
		<display-name>This is the display name of my J2EE component</display-name>
		<servlet-name>RegisterIndexServlet</servlet-name>
		<servlet-class>angelia.mvc.controller.RegisterIndexServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>RegisterIndexServlet</servlet-name>
		<url-pattern>/registerIndex</url-pattern>
	</servlet-mapping>
	
	<servlet>
		<description>This is the description of my J2EE component</description>
		<display-name>This is the display name of my J2EE component</display-name>
		<servlet-name>RegisterServlet</servlet-name>
		<servlet-class>angelia.mvc.controller.RegisterServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>RegisterServlet</servlet-name>
		<url-pattern>/register</url-pattern>
	</servlet-mapping>
	
	<servlet>
		<description>This is the description of my J2EE component</description>
		<display-name>This is the display name of my J2EE component</display-name>
		<servlet-name>LoginIndexServlet</servlet-name>
		<servlet-class>angelia.mvc.controller.LoginIndexServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>LoginIndexServlet</servlet-name>
		<url-pattern>/loginIndex</url-pattern>
	</servlet-mapping>
	
	<servlet>
		<description>This is the description of my J2EE component</description>
		<display-name>This is the display name of my J2EE component</display-name>
		<servlet-name>LoginServlet</servlet-name>
		<servlet-class>angelia.mvc.controller.LoginServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>LoginServlet</servlet-name>
		<url-pattern>/login</url-pattern>
	</servlet-mapping>
	
	<servlet>
		<description>This is the description of my J2EE component</description>
		<display-name>This is the display name of my J2EE component</display-name>
		<servlet-name>LogoutServlet</servlet-name>
		<servlet-class>angelia.mvc.controller.LogoutServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>LogoutServlet</servlet-name>
		<url-pattern>/logout</url-pattern>
	</servlet-mapping>

2.4.7 开发工具层util

public class MongdbUtil {
	public static DBCollection getDBCollection(String name) {
		System.out.println("连接Mongo");
		try {
			MongoClient mongo = new MongoClient(host, port);
			System.out.println("连接Mongo成功");
			return mongo.getDB("test").getCollection(name);// 有集合就返回,无就根据名字创建一个新的集合;
		} catch (UnknownHostException e) {
			System.out.println("连接Mongo失败");
		}
		return null;
	}
}
public class WebUtils {
	/**
	 * 将request对象转换成T对象
	 * 
	 * @param request
	 * @param clazz
	 * @return
	 */
	public static <T> T request2Bean(HttpServletRequest request, Class<T> clazz) {
		try {
			T bean = clazz.newInstance();
			Enumeration<String> e = request.getParameterNames();
			while (e.hasMoreElements()) {
				String name = (String) e.nextElement();
				BeanUtils.setProperty(bean, name, request.getParameter(name));
			}
			return bean;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

3 启动项目后访问http://localhost:8080/servlet-jsp-javabean/


4 编码web项目的国家化

4.1 编写资源文件resource_zh_CN.properties和resource_en_US.properties

website.title=Angelia的网站
language.zh=中文
language.en=英文
register=注册
login=登录
userRegister=用户注册
userName=用户名
userPwd=密码
confirmPwd=确认密码
email=邮箱
birthday=生日
reset=清空
logout=退出登陆
welcome=欢迎您
website.title=Web Site of Angelia
language.zh=ZH
language.en=EN
register=REGISTER
login=LOGIN
userRegister=User Register
userName=User Name
userPwd=Password
confirmPwd=Confirm Password
email=Email
birthday=Birthday
reset=RESET
logout=Logout
welcome=Welcome

4.2 编写资源文件读取工具类StringsUtil

public class StringsUtil {
	
	public static ResourceBundle getResources(String language){
		ResourceBundle bundle=ResourceBundle.getBundle("resource", Locale.getDefault());
		if(language!=null){
			if("zh".equals(language)){
				bundle=ResourceBundle.getBundle("resource",Locale.CHINA);
			}
			else if("en".equals(language)){
				bundle=ResourceBundle.getBundle("resource",Locale.US);
			} 
		}
		return bundle;
	}
}
4.3 编写LanguageServlet类,根据获取语言language把资源文件放到session。且web.xml配置LanguageServlet。
public class LanguageServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String language = request.getParameter("language");
        request.getSession().setAttribute("language", language);
        request.getSession().setAttribute("resources", StringsUtil.getResources(language));
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}
        <servlet>
		<servlet-name>LanguageServlet</servlet-name>
		<servlet-class>angelia.mvc.controller.LanguageServlet</servlet-class>
	</servlet>
	<servlet-mapping>
		<servlet-name>LanguageServlet</servlet-name>
		<url-pattern>/language</url-pattern>
	</servlet-mapping>

4.4 修改index.jsp,及要国家化的页面

<body>
    <h1>${resources.getString("website.title")}</h1>
    <c:choose>
        <c:when test="${language=='zh'}">
            <a href="${pageContext.request.contextPath}/language?language=en">${resources.getString("language.en")}</a>
        </c:when>
        <c:otherwise>
            <a href="${pageContext.request.contextPath}/language?language=zh">${resources.getString("language.zh")}</a>
        </c:otherwise>
    </c:choose>

    <hr />
    <c:if test="${user==null}">
        <a href="${pageContext.request.contextPath}/registerIndex" target="_blank">${resources.register}</a>
        <a href="${pageContext.request.contextPath}/loginIndex">${resources.login}</a>
    </c:if>
    <c:if test="${user!=null}">
                ${resources.getString("welcome")}:${user.userName}
            <input type="button" value="${resources.getString('logout')}" onclick="doLogout()">
    </c:if>
    <hr />
</body>

5 由于访问语言的servlet后,资源文件才会被加载。所以这样实现,直接点注册或者登陆,会出现异常。这里利用Filter,在客户端访问任何连接时,首先检查资源问价是否在session中,如不在,把资源文件加载到session。

public class LanguageFilter implements Filter {

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest)request;
		if(req.getSession().getAttribute("resources")==null){
			String language = Locale.getDefault().getLanguage();
			req.getSession().setAttribute("language", language);
			req.getSession().setAttribute("resources", StringsUtil.getResources(language));
		}
		chain.doFilter(request, response);
	}

	@Override
	public void destroy() {
	}
}
    <filter>
        <filter-name>LanguageFilter</filter-name>
        <filter-class>angelia.mvc.filter.LanguageFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>LanguageFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
5 启动项目后访问http://localhost:8080/servlet-jsp-javabean/















猜你喜欢

转载自blog.csdn.net/u014010512/article/details/80746206