案例:用户登录

用户登录案例需求

  1. 编写login.html登录页面

    username & password 两个输入框
  2. 使用Druid数据库连接池技术,操作mysql,day14数据库中user表
  3. 使用JdbcTemplate技术封装JDBC
  4. 登录成功跳转到SuccessServlet展示:登录成功!用户名,欢迎您
  5. 登录失败跳转到FailServlet展示:登陆失败!用户名或密码错误

分析

开发步骤

创建项目

创建JavaEE项目,导入 login.html 页面,druid.properties 配置文件,导入依赖 jar 包

  • login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login</title>
</head>
<body>
<form action="/day14_test/loginServlet" method="post">
用户名 <input type="text" name="username"><br/>
密码 <input type="password" name="password"><br/>
<input type="submit" value="登录">
</form>
</body>
</html>
  • druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///db3
username=root
password=root
# 初始化连接数量
initialSize=5
# 最大连接数
maxActive=10
# 最大等待时间
maxWait=3000
maxIdle=8
minIdle=3

创建数据库环境

CREATE DATABASE day14;

USE day14;

CREATE TABLE USER (
id INT PRIMARY KEY AUTO_INCREMENT, -- 编号
username VARCHAR(32) NOT NULL UNIQUE, -- 用户名
PASSWORD VARCHAR(32) NOT NULL -- 密码
);
DROP DATABASE IF EXISTS day14; SELECT * FROM USER;
INSERT INTO USER(id,username,PASSWORD) VALUES(NULL, 'superbaby','123');

创建包 com.my.domain,创建类User

package com.my.domain;

/**
* 用户的实体类
*/
public class User {
private int id;
private String username;
private String password; @Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
} public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
}
}

创建包 com.my.dao,创建类UsesrDao,提供login方法

package com.my.dao;

import com.my.domain.User;
import com.my.util.JDBCUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate; /**
* 操作数据库中 User表的类
*/
public class UserDao { // 声明JDBCTemplate对象共用
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); /**
* 登录方法
*
* @param loginUser 只有用户名和密码
* @return user包含用户全部数据,没有查询到,返回 null
*/
public User login(User loginUser) {
User user = null;
try {
// 1.编写sql
String sql = "select * from User where username = ? and password = ?";
// 2.调用query方法
user = template.queryForObject(sql,
new BeanPropertyRowMapper<User>(User.class),
loginUser.getUsername(), loginUser.getPassword());
return user;
} catch (DataAccessException e) {
e.printStackTrace(); // 后期会记录在日志
return null;
}
}
}

编写 com.my.web.servlet.LoginServlet类

package com.my.web.servlet;

import com.my.dao.UserDao;
import com.my.domain.User; 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; @WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet { @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1.设置编码,防止中文乱码
req.setCharacterEncoding("utf-8");
// 2.获取请求参数
String username = req.getParameter("username");
String password = req.getParameter("password");
// 3.封装User对象
User loginUser = new User();
loginUser.setUsername(username);
loginUser.setPassword(password); // 4.调用UserDao的login方法
UserDao dao = new UserDao();
User user = dao.login(loginUser); // 5.判断user
if (null == user) {
// 登录失败 // 转发
req.getRequestDispatcher("/failServlet").forward(req, resp);
} else {
// 登录成功 // 存储数据
req.setAttribute("user", user);
// 转发
req.getRequestDispatcher("/successServlet").forward(req, resp);
}
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.doGet(req, resp);
}
}

login.html中的form表单的action路径的写法

虚拟路径+Servlet资源路径

BeanUtils工具类,简化数据封装

  • 用于封装JavaBean的
  1. JavaBean:标准的Java类

    1. 要求:

      1. 类必须被public修饰
      2. 必须提供空参的构造器
      3. 一对getter和setter方法
      4. 成员变量必须使用private修饰
    2. 概念:
      1. 成员变量
      2. 属性:setter和getter方法截取后的产物
        • 例如:getUsername() --> Username --> username
  2. 方法
    1. setProperties():
    2. getProperties():
    3. populate(Object obj,Map map):将map集合的键值对信息,封装到对应的JavaBean对象中,把键当作属性名称,把值当作JavaBean对应的属性的值

案例:文件下载

  1. 文件下载需求

    1. 页面显示超链接
    2. 点击超链接后弹出下载提示框
    3. 完成图片文件下载
  • 分析

    1. 超链接指向的资源如果能被浏览器解析,则在浏览器中展示,如果不能解析,则弹出下载提示框。不满足需求
    2. 任何资源的下载都必须弹出下载提示框
    3. 使用响应头设置资源的打开方式:
      • content-disposition:attachment;filename=xxx
  • 步骤

    1. 定义页面,编辑超链接href属性,指向Servlet,传递资源名称filename
    2. 定义Servlet
      1. 获取文件名称(获取request参数)
      2. 使用字节输入流加载文件进内存
      3. 指定response的响应头:content-disposition:attachment;filename=xxx
      4. 将数据写出到response输出流
  • 问题:

    • 中文文件问题

      • 解决思路:

        1. 获取客户端使用的浏览器版本信息
        2. 根据不同的版本信息,设置filename的编码方式不同

代码实现

  • download.html
<a href="/day15/img/1.jpg">图片</a>
<br/>
<a href="/day15/img/2.flv">视频</a>
<hr/>
<!-- get请求在tomcat8中已解决中文乱码问题 -->
<a href="/day15/downloadServlet?filename=1.jpg">图片1</a>
<br/>
<a href="/day15/downloadServlet?filename=九尾.jpg">九尾</a>
<br/>
<a href="/day15/downloadServlet?filename=2.flv">视频</a>
  • DownloadServlet.java
package com.my.web.download;

import com.my.web.utils.DownLoadUtils;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException; /**
* 附件下载案例
*/
@WebServlet("/downloadServlet")
public class DownloadServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 1.获取请求参数,文件名称
String filename = request.getParameter("filename");
// 2.使用字节输入流加载文件进内存
// 2.1 获取ServletContext对象
ServletContext servletContext = this.getServletContext();
// 2.2 获取文件服务器真实路径
String realPath = servletContext.getRealPath("/img/" + filename); // 2.3 使用字节流关联
FileInputStream fis = new FileInputStream(realPath); // 3. 设置response的响应头
String mimeType = servletContext.getMimeType(filename); // 获取文件扩展名对应的mime类型 // 3.1 设置响应头的类型:content-type
response.setHeader("content-type", mimeType); // 3.2 设置响应头的打开方式:content-disposition // 解决中文文件名问题
// 1.获取user-agent请求头
String agent = request.getHeader("user-agent");
// 2.使用工具类方法编码文件名即可
filename = DownLoadUtils.getFileName(agent, filename); response.setHeader("content-disposition", "attachment;filename=" + filename); /*
// 简单的形式,设置编码,是在获取流之前设置
response.setContentType("text/html;charset=utf-8");
*/
// 4. 将输入流的数据写出到输出流中
ServletOutputStream sos = response.getOutputStream();
byte[] buff = new byte[1024 * 6]; // 缓冲数组
int len = 0; // 读取的有效个数
while ((len = fis.read(buff)) != -1) {
sos.write(buff, 0, len);
}
fis.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
}

JavaWebCase的更多相关文章

随机推荐

  1. MAC 上brew 更新 出错

    在MAC上brew update的时候出现报错:Error: /usr/local must be writable! 错误,在该文章中也给出解决办法(sudo chown -R $(whoami) ...

  2. 009-数组-C语言笔记

    009-数组-C语言笔记 学习目标 1.[掌握]数组的声明 2.[掌握]数组元素的赋值和调用 3.[掌握]数组的初始化 4.[掌握]数组的遍历 5.[掌握]数组在内存中的存储 6.[掌握]数组长度计算 ...

  3. 端口扫描工具nmap的常用参数讲解

    转载请注明出处:https://www.cnblogs.com/wangyanzhong123/p/12576406.html nmap下载与安装 这个没什么好说的.很简单官网上下载就ok了,需要注意 ...

  4. 技术债务(Technical debt)的产生原因及衡量解决

    第一次发布代码,就好比借了一笔钱.只要通过不断重写来偿还债务,小额负债可以加速开发.但久未偿还债务会引发危险.复用马马虎虎的代码,类似于负债的利息.整个部门有可能因为松散的实现,不完全的面向对象的设计 ...

  5. A - Number Sequence 哈希算法(例题)

    Given two sequences of numbers : a[1], a[2], ...... , a[N], and b[1], b[2], ...... , b[M] (1 <= M ...

  6. [linux] [nginx] 一键安装web环境全攻略phpstudy版,超详细!

    找到运行中的服务器(实例). 打开这个主要是看它的IP,是公网ip,公网ip,公网ip,重要的事情说三遍. 接下来我们可以不用在阿里云上操作了,直接用客户端操作,这两个客户端就是Xshell 5和Xf ...

  7. pytorch-API实现线性回归

    示例: import torch import torch.nn as nn from torch import optim class MyModel(nn.Module): def __init_ ...

  8. 对JavaScript中的this的理解

    什么是this: 解析器(就是浏览器)在调用函数时,每次都会向函数内部传递两个隐含的参数: 这两个隐含参数其中一个就是this(还有一个是arguments,用来接收函数的实参),this指向的是一个 ...

  9. 使用Idea当中的快捷键快速查看继承关系或其图表的两种方法

    一.Idea当中有两种方法可以查看继承关系 在Idea当中选中一个类,然后按Ctrl+H,可以快速查看当前所选类的继承关系,如下图: ​ 同样选中一个类,按CTRL+ALT+U,即可生成当前类的继承关 ...

  10. python信息收集(四)

        在前三篇中,我们介绍了使用python脚本发现二层.三层的主机设备,接下来我们介绍使用python发现第四层主机.     在TCP/IP协议中,第四层为传输层,主要使用的通信协议为TCP协议 ...