一、三层架构
二、MVC
三、三层架构+MVC
实际例子
操作:http://localhost:8081/login,第一次请求
操作:验证登录
//创建一个 service对象,来调用login方法
//通过login方法来来判断
//验证成功返回一个对象saveUser
//验证失败返回null
//把saveuser赋值给User
UserService service = new UserSvice();
User user = service.login(loginName,loginPwd);//在login.java中,判断User对象是否为空
//如果User != null,重定向到main.java,再转发到main.jsp
//如果User = null ,重定向到fail.jsp,在转发到fail.jsp
//或者User = null ,重定向(带上提示信息)到login.jsp,在转发到login.jsp
//一个控制器(Servlet)对应一个页面(JSP)
登录成功:
登录失败:
具体代码:
实体类(DAO层):JavaBean
package cn.edu.mju.project1.entity;
import java.io.Serializable;
import java.util.Date;
/**
* @author 友人A
* @描述 功能说明:
* @date 2020/5/1
*/
public class User {
private Integer id; //业务无关主键,用包装类,可以判断null
private String name; //姓名
private String pwd;
private String nickname;
private Integer age;
public User() {
}
public User(Integer id, String name, String pwd, String nickname, Integer age) {
this.id = id;
this.name = name;
this.pwd = pwd;
this.nickname = nickname;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
业务处理Bean(Service层):JavaBean
package cn.edu.mju.project1.service;
import cn.edu.mju.project1.entity.User;
/**
* @描述 功能说明:
* @author 友人A
* @date 2020/5/1
*/
public class UserService {
public User login(String loginName,String pwd){
/* 通过loginName条件到数据库中查找用户信息。 */
User saveUser = new User(1,"000","1234","友人A",23);
if(saveUser != null && saveUser.getName().equals(loginName)
&& saveUser.getPwd().equals(pwd)){
return saveUser;
}else {
return null;
}
}
}
登录(loginController)页面的Servlet(控制流程):
package cn.edu.mju.project1.controller;
import cn.edu.mju.project1.entity.User;
import cn.edu.mju.project1.service.UserService;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServlet;
import javax.servlet.annotation.WebServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
/*
功能:
1.接收请求参数
2.验证账号、密码、验证码
1.一般验证不写在Servlet里面(因为写在Servlet里不符合MVC模型)
2.Servlet是控制器来调用相应的Model(Service与DAO)
3.创建Service对象,调用Service对象的login()业务方法对用户进行验证。
4.验证通过,则跳转到main.jsp
5.验证没通过,则跳转到登录页面,让用户再次输入登录信息。此时页面需要给用户一些提示。
*/
//用@WebServlet注解来代替web.xml里的配置servlet的作用
@WebServlet("/login")
public class LoginController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*获取页面输出流
PrintStream out = new PrintStream(resp.getOutputStream());*/
ServletContext application = this.getServletContext();
Integer count = (Integer)application.getAttribute("count");
if( count == null){
count = new Integer(1);
}else {
count = new Integer(count.intValue()+1);
}
application.setAttribute("count",count);
req.getRequestDispatcher("/WEB-INF/template/login.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
//1.接收请求参数
String loginName = req.getParameter("loginName");
String loginPwd = req.getParameter("loginPwd");
String validCode = req.getParameter("validCode");
String saveCode = (String) req.getSession().getAttribute("code");//强制类型转换
String str = null;
if (validCode.equals("")) {
loginFail(req, resp, "请输入验证码");
} else {
if (saveCode.equals(validCode)) {
UserService service = new UserService();
User user = service.login(loginName,loginPwd);
if (user != null) {
//别的页面,也需要User的信息,所以把它保存到Session中
req.getSession().setAttribute("user",user);
//重定向
resp.sendRedirect("./main");
} else {
loginFail(req, resp, "账号或密码错误");
}
} else {
loginFail(req, resp, "验证码错误");
}
}
}
private void loginFail(HttpServletRequest req, HttpServletResponse resp, String str) throws ServletException, IOException {
//重定向,以带参数的方,把提示信息带过去。
resp.sendRedirect("./login?err="+ URLEncoder.encode(str,"UTF-8"));
}
}
登录(login.jsp)页面的JSP(显示页面):
<%@ page import="java.net.URLDecoder" %><%--
Created by IntelliJ IDEA.
User: along
Date: 2020/4/26
Time: 19:48
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" errorPage="../../errorPage.jsp" pageEncoding="UTF-8" %>
<html>
<head>
<title>登录</title>
</head>
<body>
<center>
<%
//获取参数,,进行输出
String err = request.getParameter("err");
if(err != null){
err = URLDecoder.decode(err,"UTF-8");
%>
<%= err%>
<%
}
%>
<form action="./login" method="post">
<input type="text" name="loginName" placeholder="登录名称"><br>
<input type="text" name="loginPwd" placeholder="登录密码"><br>
<input type="text" name="validCode" placeholder="验证码"><br>
<img src="./captche" id="capImg" name="capImg" onclick="javascript:this.src=this.src+'?'+Math.random()"><br>
<input type="submit" value="登录">
<input type="reset" value="取消">
<a href="#">注册</a>
<br>
访问次数:<%=application.getAttribute("count")%>
</form>
</center>
</body>
</html>
主页面(mainController)页面的Servlet(控制流程):
package cn.edu.mju.project1.controller;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 友人A
* @描述 功能说明:
* @date 2020/5/1
*/
@WebServlet("/main")
public class MainController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//准备主界面中的数据,放置到req对象里面
req.getRequestDispatcher("/WEB-INF/template/main.jsp").forward(req,resp);
}
}
验证码的Servlet:
package cn.edu.mju.project1.controller;
//导入HttpServlet包
import cn.edu.mju.project1.util.StrUtil;
import javafx.application.Application;
import javax.servlet.http.*;
import javax.servlet.annotation.WebServlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.HttpCookie;
import java.util.Random;
import static java.awt.Color.RED;
import static java.awt.Color.getColor;
//继承HttpServlet类
@WebServlet("/captche")
/**
* Servlet,用来随机生成多个字符的验证码
* @author lufanrong
*/
public class CaptcheController extends HttpServlet {
//常量命名一般全大写
private final int WIDTH = 150;
private final int HEIGHT = 80;
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String[] fontNames = {"Verdana", "Segoe UI Symbol", "SketchFlow Print", "Segoe Marker", "微软雅黑"};
Color[] colors = {Color.orange, Color.RED, Color.BLUE, Color.CYAN, Color.green, Color.pink, Color.magenta, Color.DARK_GRAY};
BufferedImage img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
//在纸上加东西
Graphics g = img.getGraphics();//创建画笔对象
g.setColor(Color.white);//设置画笔的颜色
g.fillRect(0, 0, WIDTH, HEIGHT);//画笔填充矩形背景颜色
g.setColor(RED);
String code = StrUtil.randString(4);//随机生成四个随机数
HttpSession session = req.getSession();
session.setAttribute("code", code);
Random rnd = new Random();
g.setColor(new Color(rnd.nextInt(255), rnd.nextInt(255), rnd.nextInt(255)));
int num = rnd.nextInt(5);
g.setFont(new Font(fontNames[num], Font.BOLD, 20));
// double radis = Math.toRadians(rnd.nextInt(90));
// int x = (int)(WIDTH*0.2);
// int y = (int)(HEIGHT*0.5);
// g.drawString(code.charAt(i)+" ",x,y);//字体的位置
// g.setFont(new Font("Times New Roman",Font.BOLD,18));
//
g.drawString(code, WIDTH / 3, HEIGHT / 2);//字体的位置
// g.setFont(new Font("Times New Roman",Font.BOLD,18));
g.setColor(Color.blue);
for (int i = 0; i < 100; i++) {
Random ran = new Random();
int x = ran.nextInt(WIDTH);
int y = ran.nextInt(WIDTH);
g.drawOval(x, y, 2, 2);
}
g.setColor(Color.green);
for (int i = 0; i < 10; i++) {
Random ran = new Random();
int x1 = ran.nextInt(WIDTH);
int x2 = ran.nextInt(WIDTH);
int y1 = ran.nextInt(HEIGHT);
int y2 = ran.nextInt(HEIGHT);
g.drawLine(x1, y1, x2, y2);
}
g.dispose();
//resp.getWriter()只能输出文本
ServletOutputStream out = resp.getOutputStream(); //二进制数据流,输出图片,resp:输出
ImageIO.write(img, "jpg", out);//将图片以jpg格式输出到输出流
try {
out.flush();//将缓冲区的内容提交
} finally {
out.close();//关闭传输
}
}
}