商城案例_1_涉及知識點_通用baseServlet,jsp生成驗證碼,通過郵箱發激活郵件

1.項目搭建

1.項目搭建完後,配置全站亂碼過濾器
GenericEncodingFilter.java:作用是根據請求方式,處理亂碼,同時設置返回類型

  • post方式:手動轉碼
  • get方法:自動轉碼

切記,僅僅複製GenericEncodingFilter.java是沒用的,還要去web.xml中進行配置,對所有請求進行過濾

<filter>
    <filter-name>GenericEncodingFilter</filter-name>
    <filter-class>cn.itcast.filter.GenericEncodingFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>GenericEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

2.採用通用BaseServlet
之前我們一個service中只有get和post方法,一個請求對應一個servlet,這就造成了servlet太多了

解決方法:我們希望將一個servlet管理相關一個對象的所有功能(註冊/登陸/校驗用戶名/使用一個UserServlet來解決)

首先將register.jsp的表單提交地址改爲

<form id="registForm" action="${root}/user?methodName=register" method="post" name="formUser"

實現/user對應的UserServlet

public class UserServlet extends HttpServlet {
	@Override
	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String methodName = request.getParameter("methodName");
		if(methodName.equals("register")){
			register(request,response);
		}else if(methodName.equals("login")){
			login(request,response);
		}else{
			throw new RuntimeException("當前請求的方法不存在!");
		}
	}
	
	protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("register執行了");
	}
	protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("login執行了");
	}
}

此時我們發現,如果這個servlet中需要處理的請求很多,則需要很多不用的方法,在service中也要寫很多if…else判斷,那有沒有可能就通過一段代碼就找到具體的方法呢?
答案是:反射

@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
	String methodName = request.getParameter("methodName");
	try {
		Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
		method.invoke(this, request,response);
	} catch (Exception e) {
		// TODO Auto-generated catch block
		e.printStackTrace();
	}
}

2.實現註冊功能

2.1 註冊分析

在這裏插入圖片描述

2.2 代碼實現

2.2.1 修改前端註冊頁面(register.jsp),採用baseServlet的方式向服務器發送請求
在這裏插入圖片描述
此時當我們在註冊頁面填寫好信息,提交後,就會發送如下請求
在這裏插入圖片描述
2.2.2 UserServlet實現

public class UserServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
    
	@Override
	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String methodName = request.getParameter("methodName");
		try {
			Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
			method.invoke(this, request,response);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	//註冊
	protected void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//1.獲取參數,校驗(前臺雖然已經有了校驗了,但是在後端也要進行校驗)
		String email = request.getParameter("email");
		if(StringUtils.isBlank(email)){
			//用戶名爲空
			request.setAttribute("msg", "用戶不能爲空");
			request.getRequestDispatcher("/register.jsp").forward(request, response);
			return;
		}
		String nickname = request.getParameter("nickname");
		if(StringUtils.isBlank(nickname)){
			//用戶名爲空
			request.setAttribute("msg", "暱稱不能爲空");
			request.getRequestDispatcher("/register.jsp").forward(request, response);
			return;
		}
		String password = request.getParameter("password");
		if(StringUtils.isBlank(password)){
			//用戶名爲空
			request.setAttribute("msg", "密碼不能爲空");
			request.getRequestDispatcher("/register.jsp").forward(request, response);
			return;
		}
		String confirm_password = request.getParameter("confirm_password");
		if(StringUtils.isBlank(confirm_password)){
			//用戶名爲空
			request.setAttribute("msg", "確認密碼不能爲空");
			request.getRequestDispatcher("/register.jsp").forward(request, response);
			return;
		}
		String captcha = request.getParameter("captcha");
		if(StringUtils.isBlank(confirm_password)){
			//用戶名爲空
			request.setAttribute("msg", "驗證碼不能爲空");
			request.getRequestDispatcher("/register.jsp").forward(request, response);
			return;
		}
		
		//2.判斷兩次輸入的密碼是否一致
		if(!password.equals(confirm_password)){
			request.setAttribute("msg", "兩次密碼不一致");
			request.getRequestDispatcher("/register.jsp").forward(request, response);
			return;
		}
		
		//3.驗證驗證碼
		String code = (String) request.getSession().getAttribute("code");
		if(!captcha.equals(code)){
			request.setAttribute("msg", "驗證碼不一致");
			request.getRequestDispatcher("/register.jsp").forward(request, response);
			return;
		}
		//4.將數據封裝到User對象
		User user = new User();
		try {
			BeanUtils.populate(user, request.getParameterMap());
		} catch (IllegalAccessException | InvocationTargetException e) {
			e.printStackTrace();
		}
		
		UserService service = new UserServiceImpl();
		int info = service.register(user);
		if(info == 1){
			//保存成功,跳轉到登錄頁面
			response.sendRedirect(request.getContextPath()+"/login.jsp");
			return;
		}else if(info == -1){
			//已經存在
			request.setAttribute("msg", "用戶已經存在");
			request.getRequestDispatcher("/register.jsp").forward(request, response);
			return;
		}else{
			request.setAttribute("msg", "服務器忙!!!");
			request.getRequestDispatcher("/register.jsp").forward(request, response);
			return;
		}
	}
	
	protected void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("login執行了");
	}

}

業務邏輯:
1.首先是對前臺傳遞的參數進行非空校驗,前臺雖然已經有了校驗了,但是後臺必須再進行校驗,如果有一欄是空的,就直接將錯誤信息,保存到request中,返回到註冊頁面
在這裏插入圖片描述
2.判斷兩次輸入的密碼是否一致,不一致的話講錯誤信息返回到註冊界面
3.校驗驗證碼,驗證碼是由jsp頁面生成的(之前講過如果在servlet中生成驗證碼,jsp也是servlet),且在validatecode.jsp中,再生成驗證碼後,會將驗證碼的字符串存入session
在這裏插入圖片描述
所以我們只要通過session中的驗證碼和前臺提交的驗證碼做比較就可以了
4.將數據封裝到user對象中,調用業務層,執行註冊方法,有int類型的返回值

  • 返回值1:保存用戶成功,重定向到登錄頁面
  • 返回值-1:用戶已存在,將錯誤信息返回到註冊頁面
  • 返回值2:表示在保存的過程中,出了異常了,返回一個服務器忙

注意:beanutils需要導入不少包,並不單單commons-beanutils-1.9.2.jar

2.2.3 UserService實現

public class UserServiceImpl implements UserService {
	
	private UserDao userDao = new UserDaoImpl();
	
	@Override
	public int register(User user) {
		try{
			//1.校驗用戶名是否存在
			User findByName = userDao.findByName(user.getEmail());
			if(findByName != null){
				//表示用戶已經存在,返回-1
				return -1;
			}else{
				//不存在,設置角色,激活狀態,
				user.setRole("user");
				//設置狀態,-1是未激活,此處按理說是-1,然後通過郵件去把-1改爲1
				user.setState(1);
				//設置激活碼
				String code = UUIDUtils.getUUID()+UUIDUtils.getUUID();
				user.setCode(code);
				//用戶密碼加密
				user.setPassword(MD5Utils.getPassword(user.getPassword()));
				userDao.register(user);
				
				//發送激活郵件,用戶點擊鏈接後,才激活賬戶
				//String path = "http://localhost:8080/estore/user?methodName=active&code="+code;
				//String emailMsg = "恭喜你,註冊成功,請點擊下面的鏈接進行激活<a href='"+path+"'>"+path+"</a>";
				//MailUtils.sendMail(user.getEmail(), "商城激活郵件", emailMsg);
				return 1;
			}
		}catch(Exception e){
			return 2;
		}
	}

}

1.通過郵件地址(用戶名)去校驗用戶是否存在,如果查到的對象不爲null,表示存在,此時只要返回-1
2.如果用戶不存在,表示可以註冊,我們首先設置用戶的角色(權限),激活狀態(剛註冊爲-1),激活碼,還有給密碼加密,之後我們通過dao層去註冊用戶
3.剛剛註冊的用戶,激活狀態還是-1,此時我們就通過郵件發送激活鏈接,發送到用戶留的郵件地址,當我們點擊鏈接後,修改code所對應的user的激活狀態爲1

注意點
1.用戶註冊是提供的密碼,一定要加密後再存入數據庫.因爲這種加密方式是單向的.我們之後登錄時,再用登錄密碼加密後去跟註冊時的加密密碼進行匹配
2.通過QueryRunner查找對象/集合,沒找到返回的是null

2.2.4 UserDao實現

public class UserDaoImpl implements UserDao {
	
	private QueryRunner qr = new QueryRunner(DBUtils.getDataSource());
	
	@Override
	public User findByName(String email) {
		String sql = "select * from user where email = ?";
		try {
			return qr.query(sql, new BeanHandler<User>(User.class),email);
		} catch (SQLException e) {
			throw new RuntimeException("查詢用戶失敗");
		}
	}

	@Override
	public void register(User user) {
		String sql = "insert into user values (null,?,?,?,?,?,?)";
		try {
			qr.update(sql, user.getEmail(),user.getNickname(),user.getPassword()
					,user.getRole(),user.getState(),user.getCode());
		} catch (SQLException e) {
			throw new RuntimeException("註冊用戶失敗");
		}
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章