一.request
在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求头和请求体三部分,因此,在HttpServletRequest接口中定义了获取请求行、请求头和请求消息体的相关方法.
Web服务器收到客户端的http请求,会针对每一次请求,分别创建一个用于代表请求的request对象、和代表响应的response对象。
request作用
- 操作请求三部分(行,头,体)
- 请求转发 . 转发这个请求给别人
- 作为域对象存数据 像ServletContext一样,存|取数据
操作请求行和请求头
1.获取客户机信息(操作请求行)
-
getMethod();获取请求方式
-
getRemoteAddr() ;获取客户机的IP地址(知道是谁请求的)
-
getContextPath();获得当前应用工程名(部署的路径);
-
getRequestURI();获得请求地址,不带主机名
-
getRequestURL();获得请求地址,带主机名
-
getServerPort();获得服务端的端口
-
getQueryString();获的请求参数(get请求的,URL的?后面的. eg:username=zs&password=123456)
2.获得请求头信息(操作请求头)
请求头: 浏览器告诉服务器自己的属性,配置的, 以key value存在, 可能一个key对应多个value
getHeader(String name);
- User-Agent: 浏览器信息
- Referer:来自哪个网站(防盗链)
package com.itheima._02_request;
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;
import java.util.Enumeration;
/*
* @描述: 通过request对象,获取请求行 和 请求头
*/
@WebServlet("/request01")
public class _01_request extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取请求行 GET www.baidu.com http/1.1
//http://localhost:8080/day25_request_response/request01
//method=GET
String method = req.getMethod();
System.out.println("method=" + method);
//uri=/day25_request_response/request01
String uri = req.getRequestURI();
System.out.println("uri=" + uri);
//url=http://localhost:8080/day25_request_response/request01
StringBuffer url = req.getRequestURL();
System.out.println("url=" + url);
//protocol=HTTP/1.1
String protocol = req.getProtocol();
System.out.println("protocol=" + protocol);
System.out.println("\n=-------------------------------------\n");
//2. 可以获取请求头
String ua = req.getHeader("User-Agent");
System.out.println("ua=" + ua);
// req.getHeaderNames() 获取所有的头名字
// req.getHeader("头的名字") 获取单个头的值
// req.getHeaders("头的名字") 头可能有多个值,所以用这种方法
Enumeration<String> headerNames = req.getHeaderNames();
while(headerNames.hasMoreElements()){
String header = headerNames.nextElement();
String value = req.getHeader(header);
System.out.println(header + "=" + value);
}
}
}
操作请求体(获得请求参数)
1.获得请求参数
法名 | 描述 |
---|---|
String getParameter(String name) | 获得指定参数名对应的值。如果没有则返回null,如果有多个获得第一个。 例如:username=jack |
String[] getParameterValues(String name) | 获得指定参数名对应的所有的值。此方法专业为复选框提供的。 例如:hobby=抽烟&hobby=喝酒&hobby=敲代码 |
Map<String,String[]> getParameterMap() | 获得所有的请求参数。key为参数名,value为key对应的所有的值。 |
package com.itheima._02_request;
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;
import java.util.Map;
/*
* @描述: 通过request对象,获取请求体
*/
@WebServlet("/request02")
public class _02_request extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取单个参数
String username = req.getParameter("username");
System.out.println("username=" + username);
//2. 获取所有的参数
Map<String, String[]> map = req.getParameterMap();
for(Map.Entry<String , String[]> entry : map.entrySet()){
String key = entry.getKey();
//因为有的参数可以有多个值,比如:爱好就可以传递多个值过来
String [] value = entry.getValue();
//一般来说只有一个,所以这里直接取0位置。如果有多个值,得遍历了。
System.out.println(key + "=" + value[0]);
}
}
}
2.请求参数乱码处理
我们在输入一些中文数据提交给服务器的时候,服务器解析显示出来的一堆无意义的字符,就是乱码。
那么这个乱码是如何出现的呢?如下图所示:
- get方式, 我们现在使用的tomcat>=8.0了, 乱码tomcat已经处理好了
- post方式, 就需要自己处理
package com.itheima._02_request;
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;
/*
* @描述: 通过request对象,获取请求体
* 执行post请求,携带中文数据。
*/
@WebServlet("/request03")
public class _03_request extends HttpServlet{
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//在取数据之前,先告诉servlet用什么编码去取数据
//如果不设置,默认取值的时候,采用iso-8859-1的编码取值。这肯定就有乱码了。
req.setCharacterEncoding("UTF-8");
String username = req.getParameter("username");
System.out.println("username=" + username);
String password = req.getParameter("password");
System.out.println("password=" + password);
}
}
3.使用BeanUtils封装
现在我们已经可以使用request对象来获取请求参数,但是,如果参数过多,我们就需要将数据封装到对象。
以前封装数据的时候,实体类有多少个字段,我们就需要手动编码调用多少次setXXX方法,因此,我们需要BeanUtils来解决这个问题。
BeanUtils是Apache Commons组件的成员之一,主要用于简化JavaBean封装数据的操作。
使用步骤:
- 导入jar
commons-beanutils-1.8.3.jar 和 commons-logging-1.1.1.jar
- 使用BeanUtils.populate(user,map)
package com.itheima._02_request;
import com.itheima.bean.User;
import org.apache.commons.beanutils.BeanUtils;
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;
import java.lang.reflect.InvocationTargetException;
import java.util.Map;
/*
* @描述: 获取到参数之后,打包成一个对象。
*/
@WebServlet("/request04")
public class _04_request extends HttpServlet{
//这个doGet方法不会执行,如果执行的请求方式是post
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/* //1. 获取数据
String username = req.getParameter("username");
String password = req.getParameter("password");
String address = req.getParameter("address");
String phone = req.getParameter("phone");
//2. 封装对象
User user = new User(username , password , address , phone);
System.out.println("user=" + user);
*/
try {
//1. 获取参数 还有一些特殊的地方,爱好,,有三个数据,???
Map<String, String[]> map = req.getParameterMap();
//2. 创建对象
User u = new User();
//3. 把参数封装到对象身上
BeanUtils.populate(u , map);
//4. 打印一下
System.out.println("u=" + u);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
- 如果请求参数有多个需要封装到JavaBean里面, 建议先获得Map, 再使用BeanUtils封装到JavaBean对象
注意: JavaBean属性需要和Map的key一致 说白了也就是JavaBean属性需要和表单的name一致
请求转发forward
- 请求转发的本质就是: 跳转 ,不能跳转到外部的资源,只能跳转到项目内部的资源。
request.getRequestDispatcher(url).forward(request, response); //转发
package com.itheima._02_request._02;
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;
/*
* @描述: TODO
*/
@WebServlet("/request0201")
public class _01_request extends HttpServlet {
@Override
protected void doGet(HttpServletRequest requset, HttpServletResponse response) throws ServletException, IOException {
System.out.println("来了一个get请求2...");
//处理完请求,可以让请求跳转到别的地方去。可以跳转一个页面,可以跳转到网站。
//外面的资源路径,跳转不了
//req.getRequestDispatcher("http://www.baidu.com").forward(req ,resp);
//跳转到项目自己内部的资源
//requset.getRequestDispatcher("login.html").forward(requset,response);
requset.getRequestDispatcher("/WEB-INF/register.html").forward(requset,response);
}
}
- 请求的路径不会变化
- 一次请求
- 转发可以转发到WEB-INF里面的资源 (WEB-INF的资源,不能直接访问,可以通过servlet进行跳转访问)
作为域对象存取值
ServletContext: 可以存|取值,范围是整个应用程序, AServlet 存值, BServlet能取值
request范围: 一次请求内有效!!!
域对象是一个容器,这种容器主要用于Servlet与Servlet/JSP之间的数据传输使用的。
- Object getAttribute(String name) ;
- void setAttribute(String name,Object object) ;
- void removeAttribute(String name) ;
FirstServlet
package com.itheima._02_request._03;
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;
/*
* @创建时间: 2020/7/28 11:54
* @描述: request存值和取值
*/
@WebServlet("/first")
public class FirstServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//存值
req.setAttribute("username" , "张三");
//自己取值
String username = (String) req.getAttribute("username");
System.out.println("FirstServlet::username=" + username);;
System.out.println("first::hashcode" + req.hashCode());
System.out.println("使用请求转发跳转到SecondServlet" );
//使用请求转发的方式跳转到SecondServlet
req.getRequestDispatcher("second").forward(req,resp);
}
}
SecondServlet
package com.itheima._02_request._03;
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;
/*
* @创建时间: 2020/7/28 11:54
* @描述: request存值和取值
*/
@WebServlet("/second")
public class SecondServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("second::hashcode" + req.hashCode());
//取值
String username = (String) req.getAttribute("username");
System.out.println("SecondServlet::username=" + username);;
}
}
二.Response
在Servlet API中,定义了一个HttpServletResponse接口(doGet,doPost方法的参数),它继承自ServletResponse接口,专门用来封装HTTP响应消息。由于HTTP响应消息分为响应行、响应头、响应体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码、响应头、响应体的方法
- Response代表响应对象. 原型是HttpServletResponse, 服务器(Tomcat)创建的, 以形参的形式存在doGet()/doPost()方法
- Response的作用
- 操作响应的三部分(行, 头, 体)
操作响应行
HTTP/1.1 200
常用的状态码:
200:成功
302:重定向
304:访问缓存
404:客户端错误
500:服务器错误
操作响应头
响应头: 是服务器指示浏览器去做什么
一个key对应一个value
一个key对应多个value
关注的方法: setHeader(String name,String value);
常用的响应头
Refresh:定时跳转 (eg:服务器告诉浏览器5s之后跳转到百度)
Location:重定向地址(eg: 服务器告诉浏览器跳转到xxx)
Content-Disposition: 告诉浏览器下载
Content-Type:设置响应内容的MIME类型(服务器告诉浏览器内容的类型)
1.定时刷新
package com.itheima._03_response;
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;
/*
* @描述: TODO
*/
@WebServlet("/response01")
public class _01_response extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("来了一个请求");
//给人家反馈
//1. 设置响应行 http/1.1 200
//resp.setStatus(404);
//resp.setStatus(500 , "Internal server error");
//设置响应头 告诉浏览器过5秒钟之后,打开指定的网址。
resp.setHeader("Refresh" , " 5; url=http://www.itheima.com");
}
}
2. 重定向–跳转
- 重定向两次请求
- 重定向的地址栏路径改变
- 重定向的路径写绝对路径(带域名/ip地址的, 如果是同一个项目里面的,域名/ip地址可以省略)
- 重定向的路径可以是项目内部的,也可以是项目以外的(eg:百度)
- 重定向不能重定向到WEB-INF下的资源
- 把数据存到request里面, 重定向不可用
package com.itheima._03_response;
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;
/*
* @描述: 使用response进行页面跳转,
*/
@WebServlet("/response02")
public class _02_response extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("来了一个请求");
/*
//1. 直接跳转到外面去。
//a. 设置状态码,302 的意思就是告诉浏览器,还要去另一个地方。
resp.setStatus(302);
//Location: http://www.zcmhi.com/archives/94.html
//resp.setHeader("Location" , "http://www.baidu.com");
resp.setHeader("Location" , "login.html");
*/
//-----------------------------较为简单的写法-------------------------------
resp.sendRedirect("http://www.itheima.com");
}
}
3.重定向sendRedirect
重定向 response.sendRedirect(“重定向的路径”)
- 重定向两次请求
- 重定向的地址栏路径改变
- 重定向的路径写绝对路径, 带域名/ip地址的(如果路径在同一个项目里面,域名/ip地址可以省略的)
- 重定向的路径可以写项目内部的, 也可以写项目外部的(eg: 百度)
转发和重定向区别
- 重定向可以跳转到外面的资源(网站) , 请求转发跳转不了(只能跳转项目内部资源,因为这是由tomcat来完成)
- 请求转发只有一次请求,重定向有两次请求。
- 请求转发的地址栏不会改变,但是重定向的地址栏会发生改变。
- 请求转发和重定向都能跳转到servlet。
- AServlet (request)存值 ----请求转发—到BServlet , 在BServlet里面能取值。
- AServlet (request)存值 ----重定向—到BServlet , 在BServlet里面不能取值!!。
- 因为WEB-INF 文件夹是受保护的,只能由项目内部跳转,所以请求转发可以跳转到里面的资源,但是重定向不行(因为重定向是从浏览器开始)
操作响应体
1.操作响应体的API
页面输出只能使用其中的一个流实现,两个流是互斥的
2.响应乱码处理
- 解决字符流输出中文乱码问题
response.setContentType(“text/html;charset=utf-8”);
- 使用字节输出流输出中文乱码问题
//设置浏览器打开方式
response.setHeader("Content-type", "text/html;charset=utf-8");
//得到字节输出流
ServletOutputStream outputStream = response.getOutputStream();
outputStream.write("你好".getBytes("utf-8"));// 使用平台的默认字符(utf-8)集将此 String 编码为 byte 序列
package com.itheima._03_response;
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;
/*
* @描述: 使用response对象操作响应体
*
* 1. 字符流写数据
*
* 2. 字节流写数据
*/
@WebServlet("/response03")
public class _03_response extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("来了一个请求");
//0. 设置响应的内容类型。
//resp.setContentType("text/html");
//解决乱码?
//resp.setCharacterEncoding("UTF-8");
//00. 既设置了内容的类型,也设置了内容的编码
resp.setContentType("text/html;charset=utf-8");
//1. 字符流写数据 如果是字符流,就写上面的resp.setContentType("text/html;charset=utf-8")
//resp.getWriter().write("<h2><font color='red'>我又又成功啦===success!!!!!</font></h2>");
//2. 使用字节流写数据 在后面的getBytes里面写上 字符集
resp.getOutputStream().write("<h2><font color='red'>我想成功!===success!!!!!</font></h2>".getBytes("utf-8"));
}
}
-
为什么会出现乱码?
- iso8859-1不支持中文
- 编码和解码不一致
-
乱码解决
-
请求乱码
- get方式, tomcat>=8.0 不需要解决, 服务器已经解决好了
- post方式
request.setCharacterEncoding("utf-8");
- 响应乱码
response.setContentType("text/html;charset=utf-8");
-
文件下载
1.需求分析
- 创建文件下载的列表的页面,点击列表中的某些链接,下载文件.
2.文件下载分析
2.1什么是文件下载
将服务器上已经存在的文件,输出到客户端浏览器.
说白了就是把服务器端的文件拷贝一份到客户端, 文件的拷贝—> 流(输入流和输出流)的拷贝
2.2文件下载的方式
-
第一种:超链接方式(不推荐)
链接的方式:直接将服务器上的文件的路径写到href属性中.如果浏览器不支持该格式文件,那么就会提示进行下载, 如果 浏览器支持这个格式(eg: png, jpg…)的文件,那么直接打开,不再下载了
-
第二种:手动编码方式(推荐)
手动编写代码实现下载.无论浏览器是否识别该格式的文件,都会下载.
3.思路分析
3.1超链接方式
- 准备下载的资源(文件)
- 编写一个下载页面
- 在这个页面上定义超链接,指定href
3.2编码方式
3.2.1手动编码方式要求
设置两个头和一个流
设置的两个头:
Content-Dispostion: 服务器告诉浏览器去下载
Content-Type: 告诉浏览器文件类型.(MIME的类型)
设置一个流:
获得要下载的文件的输入流.
3.2.2思路
4.代码实现
package com.itheima._05_filedownload;
/*
* @描述: 文件下载的servlet
*/
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;
import java.io.InputStream;
import java.io.OutputStream;
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 获取要下载的文件名称,通过参数传递进来的
String fileName = req.getParameter("file"); //a.jpg
//2. 根据文件找到得到该文件的输入流
// FileInputStream fis = new FileInputStream();
InputStream fis = getServletContext().getResourceAsStream("download/"+fileName);
if(fis == null){
System.out.println("文件路径错误!!!");
}
//设置一下文件的类型,以及告诉浏览器要下载。
String mimeType = getServletContext().getMimeType(fileName);
resp.setContentType(mimeType);
resp.setHeader("Content-Disposition" , "attachment;filename="+fileName);
//3. 使用字节流的方式写给浏览器
OutputStream os = resp.getOutputStream();
byte [] buffer = new byte[1024];
int len = 0 ;
while( (len = fis.read(buffer)) != -1 ){
os.write(buffer , 0 , len);
}
os.close();
fis.close();
}
}
5.细节处理
-
告诉浏览器设置的响应头里面不支持中文的, 抓包来看:
-
解决方案: 手动进行编码再设置进去就ok了
中文文件在不同的浏览器中编码方式不同:火狐是Base64编码, 其它浏览器(谷歌)是URL的utf-8编码
if(agent.contains("Firefox")){
// 火狐浏览器
filename = base64EncodeFileName(filename);
}else{
// IE,其他浏览器
filename = URLEncoder.encode(filename, "UTF-8");
}
public static String base64EncodeFileName(String fileName) {
BASE64Encoder base64Encoder = new BASE64Encoder();
try {
return "=?UTF-8?B?"
+ new String(base64Encoder.encode(fileName
.getBytes("UTF-8"))) + "?=";
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
综合案例
案例-注册
1. 需求
2. 路径
- 三层结构的讲解
- 完成注册功能
3. 代码实现
3.1 三层架构
-
软件中分层:按照不同功能分为不同层,通常分为三层:表现层(web层),业务层,持久(数据库)层。
-
不同层次包名的命名
分层 | 包名(公司域名倒写) |
---|---|
表现层(web层) | com.free.web |
业务层(service层) | com.free.service |
持久层(数据库访问层) | com.free.dao |
JavaBean | com.free.bean |
工具类 | com.free.utils |
- 分层的意义:
- 解耦:降低层与层之间的耦合性。
- 可维护性:提高软件的可维护性,对现有的功能进行修改和更新时不会影响原有的功能。
- 可扩展性:提升软件的可扩展性,添加新的功能的时候不会影响到现有的功能。
- 可重用性:不同层之间进行功能调用时,相同的功能可以重复使用。
3.2 完成注册案例
3.2.1 注册案例思路
3.2.2准备工作
- 数据库
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`nickname` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`address` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`gender` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`hobby` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`email` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Compact;
- JavaBean
package com.itheima.bean;
import java.util.Arrays;
/*
* @描述: TODO
*/
public class User02 {
private String username;
private String password;
private String nickname;
private String address;
private String email;
private String gender;
private String [] hobby;
public User02() {
}
public User02(String username, String password, String nickname, String address, String email, String gender, String[] hobby) {
this.username = username;
this.password = password;
this.nickname = nickname;
this.address = address;
this.email = email;
this.gender = gender;
this.hobby = hobby;
}
...get方法和set方法...
}
- 导入jar
- 工具类和配置文件
- c3p0-config.xml
<c3p0-config>
<default-config>
<!--连接数据库的信息-->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property>
<property name="user">root</property>
<property name="password">root</property>
<!--连接池的配置-->
<property name="automaticTestTable">con_test</property>
<property name="checkoutTimeout">30000</property>
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
<user-overrides user="test-user">
<property name="maxPoolSize">10</property>
<property name="minPoolSize">1</property>
<property name="maxStatements">0</property>
</user-overrides>
</default-config>
</c3p0-config>
- register.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h2>用户注册</h2>
<form method="post" action="register">
姓名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
昵称:<input type="text" name="nickname"/><br/>
地址:<input type="text" name="address"/><br/>
邮箱:<input type="text" name="email"/><br/>
性别: <input type="radio" name="gender" checked="checked" value="女"> 女 <input type="radio" name="gender" value="男"> 男 <br/>
爱好: <input type="checkbox" name="hobby" value="抽烟"/> 抽烟
<input type="checkbox" name="hobby" value="喝酒"/> 喝酒
<input type="checkbox" name="hobby" value="烫头"/> 烫头<br/>
<input type="submit" value="注册"/>
</form>
</body>
</html>
3.2.3 注册案例实现
package com.itheima._06_UserDemo;
import com.itheima.bean.User02;
import com.itheima.db.C3p0Util;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.dbutils.QueryRunner;
import javax.servlet.ServletConfig;
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;
import java.util.Arrays;
import java.util.Map;
/*
* @创建时间: 2020/7/28 16:42
* @描述: TODO
*/
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
//要想让init方法调用的时机提前 ,还要再web.xml中配置一句话
// <load-on-startup>1</load-on-startup>
@Override
public void init(ServletConfig config) throws ServletException {
// QueryRunner runner = new QueryRunner(C3p0Util.getDataSource());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
try {
//0. 设置编码
req.setCharacterEncoding("UTF-8");
//1. 获取数据
Map<String, String[]> parameterMap = req.getParameterMap();
//2. 封装到javabean
User02 user = new User02();
BeanUtils.populate(user , parameterMap);
System.out.println("user=" + user);
String hobby = Arrays.toString(user.getHobby());
//3. 往数据库里面添加记录
QueryRunner runner = new QueryRunner(C3p0Util.getDataSource());
String sql = "insert into user values (null , ?,?,?,?,?,?,?)";
int row = runner.update(sql ,
user.getUsername(),
user.getPassword(),
user.getNickname(),
user.getAddress(),
user.getGender(),
hobby.substring(1 ,hobby.length()-1),
user.getEmail()
);
if(row > 0){
System.out.println("注册成功");
}else{
System.out.println("注册失败");
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
4. 小结
- 注册本质: 向数据库插入一条记录
- 思路(在RegisterServlet)
- 获得用户提交的数据, 使用BeanUtils封装成User对象
- 补全User对象(状态)
- 使用DBUtils向数据库里面插入一条记录
- 响应
案例-登录
1.需求
- 点击登录按钮, 进行登录.
- 登录成功,显示login Success
- 登录失败,显示login failed
2.思路
3.代码实现
3,1准备工作
- 页面的准备 login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<center>
<h1>用户登录</h1>
<form action="login" method="post">
姓名:<input type="text" name="username"/><br/>
密码:<input type="password" name="password"/><br/>
<input type="submit" value="登录"/>
</form>
</center>
</body>
</html>
3.2代码实现
package com.itheima.web;
import com.itheima.bean.User;
import com.itheima.utils.C3P0Utils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
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;
import java.sql.SQLException;
/**
* @Description:
* @Author: yp
*/
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
//0.处理乱码
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=utf-8");
//1.获得用户名和密码
String username = request.getParameter("username");
String password = request.getParameter("password");
//2.使用DBUtils根据用户名和密码查询数据库 封装成User对象
QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());
String sql = "SELECT * FROM user WHERE username = ? AND password =?";
User user = queryRunner.query(sql, new BeanHandler<User>(User.class), username, password);
//3.判断是否登录成功(判断User是否为null)
if (user != null){
//3.1 user!= null 响应登录成功
response.getWriter().print("登录成功!欢迎回来:"+user.getNickname());
}else{
//3.2 user== null 响应登录失败
response.getWriter().print("登录失败!");
}
} catch (Exception e) {
e.printStackTrace();
response.getWriter().print("登录失败!");
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
4.小结
- 本质: 就是根据用户名和密码查询数据库
- 思路(LoginServlet)
- 获得用户输入用户名和密码
- 使用DBUtils根据用户名和密码查询数据库 封装成User对象
- 判断是否登录成功(判断User是否为null)
- 响应
转载:https://blog.csdn.net/weixin_41942838/article/details/116176164