码迷,mamicode.com
首页 > Web开发 > 详细

使用Maven构建Web应用(下)

时间:2015-07-29 23:05:15      阅读:154      评论:0      收藏:0      [点我收藏+]

标签:maven   web应用   java   管理   

上篇account-service中已经封装了实现细节,所以接下来只要在此次基础上提供Web页面,并使用简单servlet,jsp与后台实现交互控制。以下是account-web模块的构成:

  • POM部分
<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>
	<parent>
		<groupId>com.juvenxu.mvnbook.account</groupId>
		<artifactId>account-parent</artifactId>
		<version>1.0.0-SNAPSHOT</version>
	</parent>

	<artifactId>account-web</artifactId>
	<packaging>war</packaging>
	<name>Account Web</name>

	<dependencies>
		<dependency>
			<groupId>${project.groupId}</groupId>
			<artifactId>account-service</artifactId>
			<version>${project.version}</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet-api</artifactId>
			<version>2.5</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>jsp-api</artifactId>
			<version>2.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.1.7.RELEASE</version>
		</dependency>
	</dependencies>
</project>
上述代码中,account-web的packaging元素值为war,表示这是一个Web项目,需要以war方式打包。account-web依赖于servlet-api和jsp-api这两个几乎所有Web项目都要依赖的包,它们为servlet和jsp的编写提供支持。这里依赖范围是provided,表示它们不会被打包到war中,这是因为几乎所有Web容器都会提供这两个类库,如果war包中重复出现,就会导致依赖冲突等问题。account-web还依赖于account-service和spring-web,前者为Web应用提供底层支持,后者为Web应用提供Spring的集成支持。

在一些Web项目中,可能会有finalName的配置。该元素用来标识项目生成的主构件名称,该元素默认值已在超级POM中设定,值为${project.artifactId}-${project.version}。我们可以通过<finalName>account</finalName>的配置修改主构件名称为account,之后项目生成的war包名称就会成为account.war,更方便部署。

  • 主代码部分
主代码包含了2个JSP页面和4个Servlet,分别是:
  1. signup.jsp:账户注册页面
  2. login.jsp:账户登陆页面
  3. CaptchaImageServlet:生成验证码图片的Servlet
  4. LoginServlet:处理账户注册请求
  5. ActivateServlet:处理账户激活
  6. LoginServlet
不过首先要在web.xml中配置Servlet,该文件位于src/main/webapp/WEB-INF/目录下。配置如下:
//web.xml
<?xml version="1.0" encoding="UTF-8"?>
<!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>Account Service</display-name>
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			classpath:/account-persist.xml
			classpath:/account-captcha.xml
			classpath:/account-email.xml
			classpath:/account-service.xml
		</param-value>
	</context-param>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<servlet>
		<servlet-name>CaptchaImageServlet</servlet-name>
		<servlet-class>com.juvenxu.mvnbook.account.web.CaptchaImageServlet</servlet-class>
	</servlet>
	<servlet>
		<servlet-name>ActivateServlet</servlet-name>
		<servlet-class>com.juvenxu.mvnbook.account.web.ActivateServlet</servlet-class>
	</servlet>
	<servlet>
		<servlet-name>LoginServlet</servlet-name>
		<servlet-class>com.juvenxu.mvnbook.account.web.LoginServlet</servlet-class>
	</servlet>
	<servlet>
		<servlet-name>SignUpServlet</servlet-name>
		<servlet-class>com.juvenxu.mvnbook.account.web.SignUpServlet</servlet-class>
	</servlet>

	<servlet-mapping>
		<servlet-name>CaptchaImageServlet</servlet-name>
		<url-pattern>/captcha_image</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>SignUpServlet</servlet-name>
		<url-pattern>/signup</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>ActivateServlet</servlet-name>
		<url-pattern>/activate</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
		<servlet-name>LoginServlet</servlet-name>
		<url-pattern>/login</url-pattern>
	</servlet-mapping>
</web-app>
该web.xml首先配置了Web项目的显示名称,接着是一个名为ContextLoaderListener的ServletListener。该Listener来自于spring-web,用来为Web项目启动Spring的IoC容器,从而实现Bean的注入。名为contextConfigLocation的caontext-param则用来为指定的Spring配置文件的位置。这里的值是四个模块的Spring配置XML文件,例如classpath:/account-persist.xml表示从classpath的根路径获取名为account-persist.xml的文件。我们知道account-persist.xml文件在account-persist模块打包后的根路径下,这一JAR文件通过依赖的方式被引入到account-web的classpath下。web.xml中的其余部分是Servlet,包括各个Servlet的名称,类名以及相应的URL模式。

下面再构建视图文件signup.jsp文件,用来显示账户注册页面,存放在src/main/webapp/目录下。
<%@ page language="java" pageEncoding="UTF-8"
	contentType="text/html; charset=UTF-8"%>
<%@ page
	import="org.springframework.web.context.support.WebApplicationContextUtils"%>
<%@ page import="org.springframework.web.context.WebApplicationContext"%>
<%@ page import="org.springframework.context.ApplicationContext"%>
<%@ page import="com.juvenxu.mvnbook.account.service.*"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme() + "://"
			+ request.getServerName() + ":" + request.getServerPort()
			+ path + "/";
%>

<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath%>">
<title>SignUp Page</title>

<style type="text/css">
.text-field {
	position: absolute;
	left: 40%;
	background-color: rgb(255, 230, 220);
}

label {
	display: inline-table;
	width: 90px;
	margin: 0px 0px 10px 20px;
}

input {
	display: inline-table;
	width: 150px;
	margin: 0px 20px 10px 0px;
}

img {
	width: 150px;
	margin: 0px 20px 10px 110px;
}

h2 {
	margin: 20px 20px 20px 40px;
}

button {
	margin: 20px 20px 10px 110px
}
</style>
</head>

<body>
	<%
		//引入Spring的ApplicationContext类
		ApplicationContext context = WebApplicationContextUtils
				.getWebApplicationContext(getServletContext());
		//加载后台的AccountService对象
		AccountService accountService = (AccountService) context
				.getBean("accountService");
		//使用该对象生成一个验证码的key
		String captchaKey = accountService.generateCaptchaKey();
	%>
	<div class="text-field">

		<h2>注册新账户</h2>
		<form name="signup" action="signup" method="post">
			<label>账户ID:</label>
			<input type="text" name="id"/><br/> 
			<label>Email:</label>
			<input type="text" name="email"/><br/> 
			<label>显示名称:</label>
			<input type="text" name="name"/><br/> 
			<label>密码:</label>
			<input type="password" name="password"/><br/> 
			<label>确认密码:</label>
			<input type="password" name="confirm_password"/><br/> 
			<label>验证码:</label>
			<input type="text" name="captcha_value"/><br/> 
			<input type="hidden" name="captcha_key" value="<%=captchaKey%>"/> 
			<img src="<%=request.getContextPath()%>/captcha_image?key=<%=captchaKey%>"/><br/>
			<button>确认并提交</button>
		</form>
	</div>
</body>
</html>
上述JSP中使用/captcha_image这一资源获取验证码图片。根据web.xml,该资源对应于CaptchaImageServlet,所有Servlet都放在src/main/java/目录下,代码如下:
//CaptchaImageServlet.java
package com.juvenxu.mvnbook.account.web;

import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.juvenxu.mvnbook.account.service.AccountService;
import com.juvenxu.mvnbook.account.service.AccountServiceException;

@SuppressWarnings("serial")
public class CaptchaImageServlet extends HttpServlet {
	private ApplicationContext context; // Spring的ApplicationContext

	@Override
	/**
	 * 首先初始化ApplicationContext
	 */
	public void init() throws ServletException {
		super.init();
		context = WebApplicationContextUtils
				.getWebApplicationContext(getServletContext());
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 获取key参数
		String key = request.getParameter("key");
		// 检查key是否为空
		if (key == null || key.length() == 0) {
			// 返回HTTP400错误,请求不合法
			response.sendError(400, "No Captcha Key Found");
		} else {
			// 获取Spring Bean并强制类型转换
			AccountService service = (AccountService) context
					.getBean("accountService");

			try {
				// 设置response格式为image/jpeg
				response.setContentType("image/jpeg");
				// 将产生的字节流写入到Servlet的输出流中
				OutputStream out = response.getOutputStream();
				out.write(service.generateCaptchaImage(key));
				out.close();
			} catch (AccountServiceException e) {
				response.sendError(400, e.getMessage());
			}
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doGet(request, response);
	}
}
而signup.jsp中form表单的action是signup,根据web.xml对应于SignUpServlet,代码如下:
//SignUpServlet.java
package com.juvenxu.mvnbook.account.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.juvenxu.mvnbook.account.service.AccountService;
import com.juvenxu.mvnbook.account.service.AccountServiceException;
import com.juvenxu.mvnbook.account.service.SignUpRequest;

@SuppressWarnings("serial")
public class SignUpServlet extends HttpServlet {
	private ApplicationContext context; // 用于获取Spring Bean

	@Override
	/**
	 * 首先初始化ApplicationContext
	 */
	public void init() throws ServletException {
		super.init();
		context = WebApplicationContextUtils
				.getWebApplicationContext(getServletContext());
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// 获取HTTP POST请求,读取表单中的id,邮箱,用户名,密码,确认密码,验证主键,验证值参数
		String id = req.getParameter("id");
		String email = req.getParameter("email");
		String name = req.getParameter("name");
		String password = req.getParameter("password");
		String confirmPassword = req.getParameter("confirm_password");
		String captchaKey = req.getParameter("captcha_key");
		String captchaValue = req.getParameter("captcha_value");
		// 判断各参数是否为空,存在为空值则返回报错
		if (id == null || id.length() == 0 || email == null
				|| email.length() == 0 || name == null || name.length() == 0
				|| password == null || password.length() == 0
				|| confirmPassword == null || confirmPassword.length() == 0
				|| captchaKey == null || captchaKey.length() == 0
				|| captchaValue == null || captchaValue.length() == 0) {
			resp.sendError(400, "Parameter Incomplete.");
			return;
		}
		// 获取名为accountService的bean
		AccountService service = (AccountService) context
				.getBean("accountService");
		// 初始化一个SignUpRequest实例并设置其属性
		SignUpRequest request = new SignUpRequest();
		request.setId(id);
		request.setEmail(email);
		request.setName(name);
		request.setPassword(password);
		request.setConfirmPassword(confirmPassword);
		request.setCaptchaKey(captchaKey);
		request.setCaptchaValue(captchaValue);
		request.setActivateServiceUrl(getServletContext().getRealPath("/")
				+ "activate"); // 发送账户激活邮件的地址,这里是ActivateServlet的地址
		// 使用AccountService注册用户
		try {
			service.signUp(request);
			resp.getWriter()
					.print("Account is created, please check your mail box for activation link.");
		} catch (AccountServiceException e) {
			resp.sendError(400, e.getMessage());
			return;
		}
	}
}
在这里又用到了ActivateServlet,代码如下:
//ActivateServlet
package com.juvenxu.mvnbook.account.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.juvenxu.mvnbook.account.service.AccountService;
import com.juvenxu.mvnbook.account.service.AccountServiceException;

@SuppressWarnings("serial")
public class ActivateServlet extends HttpServlet {
	private ApplicationContext context;

	@Override
	public void init() throws ServletException {
		super.init();
		context = WebApplicationContextUtils
				.getWebApplicationContext(getServletContext());
	}

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String key = req.getParameter("key");
		// 判断激活码是否为空
		if (key == null || key.length() == 0) {
			resp.sendError(400, "No activation key provided.");
			return;
		}
		AccountService service = (AccountService) context
				.getBean("accountService");
		// 激活账户
		try {
			service.activate(key);
			resp.getWriter().write("Account is activated, now you can login.");
		} catch (AccountServiceException e) {
			resp.sendError(400, "Unable to activate account");
			return;
		}
	}
}
以上是注册页面及相关逻辑处理的实现。另外一个页面是login.jsp,负责处理登录。
<%@ page contentType="text/html; charset=UTF-8" language="java"%>
<html>
<head>
<style type="text/css">
.text-field {
	position: absolute;
	left: 40%;
	background-color: rgb(255, 230, 220);
}

label {
	display: inline-table;
	width: 90px;
	margin: 0px 0px 10px 20px;
}

input {
	display: inline-table;
	width: 150px;
	margin: 0px 20px 10px 0px;
}

h2 {
	margin: 20px 20px 20px 40px;
}

button {
	margin: 20px 20px 10px 110px
}
</style>
</head>
<body>
	<div class="text-field">
		<h2>账户登录</h2>
		<form name="login" action="login" method="post">
			<label>账户ID:</label>
			<input type="text" name="id"/><br/>
			<label>密码:</label>
			<input type="password" name="password"/><br/>
			<button>确认并提交</button>
		</form>
	</div>
</body>
</html>
表单的action是login,LoginServlet代码如下:
//LoginServlet.java
package com.juvenxu.mvnbook.account.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.juvenxu.mvnbook.account.service.AccountService;
import com.juvenxu.mvnbook.account.service.AccountServiceException;

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet {
	private ApplicationContext context;

	@Override
	public void init() throws ServletException {
		super.init();
		context = WebApplicationContextUtils
				.getWebApplicationContext(getServletContext());
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		String id = req.getParameter("id");
		String password = req.getParameter("password");

		if (id == null || id.length() == 0 || password == null
				|| password.length() == 0) {
			resp.sendError(400, "incomplete parameter");
			return;
		}

		AccountService service = (AccountService) context
				.getBean("accountService");

		try {
			service.login(id, password);
			resp.getWriter().print("Login Successful!");
		} catch (AccountServiceException e) {
			resp.sendError(400, e.getMessage());
		}
	}
}
由于代码格式及内容和上面的非常相似,所以这里省略了注释,大部分代码可以参考SignUpServlet。
最后在在src/main/resources/目录下建立一个配置文件,account-service.properties,具体配置参见前面邮箱的配置,示例如下
//account.service.properties
email.protocol=smtp
email.host=localhost
email.port=25
email.username=zachary@mymail.com
email.password=123456
email.auth=true
email.systemEmail=test@mymail.com
persist.file=C\:/persist-data.xml



这样一个maven的Web项目就构建完了。在account-web的目录上执行mvn clean install,该项目的WAR包就被打包到了本地仓库上。

参考书籍:《Maven实战》第12章——许晓斌著

版权声明:本文为博主原创文章,未经博主允许不得转载。

使用Maven构建Web应用(下)

标签:maven   web应用   java   管理   

原文地址:http://blog.csdn.net/zhang_zp2014/article/details/47109635

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!