一 Servlet 常见配置问题
1. 解决无法自动导入 HTTPServlet 包的问题
2. TomCat 移动盘符后 ,修改配置
3. 部署工件出错
第一种情况. 注意@WebServlet的路径不能相同
第二种情况.导入jia包
4. TomCat 9 控制台乱码问题
在末尾加上这两行 -Dfile.encoding=UTF-8 -Deditable.java.test.console=true
或者在虚拟机选项填入 -Dfile.encoding=UTF-8
5. 无法直接创建 Servlet 类
6. Tomcat7 参数乱码问题
将参数 :rname = new String(rname.getBytes("iso-8859-1"),"utf-8");
一. HTTP协议:
1. 概念
2. 请求消息数据格式
3. 响应消息的数据格式
二 Request对象
1. request和response的原理 _request对象继承体系结构:
2. request功能:
代码演示:
//1. 获取请求方式 :GET
String method = request.getMethod();
System.out.println(method);
//2.(*)获取虚拟目录:/day14
String contextPath = request.getContextPath();
System.out.println(contextPath);
//3. 获取Servlet路径: /demo1
String servletPath = request.getServletPath();
System.out.println(servletPath);
//4. 获取get方式请求参数:name=zhangsan
String queryString = request.getQueryString();
System.out.println(queryString);
//5.(*)获取请求URI:/day14/demo1
String requestURI = request.getRequestURI();
StringBuffer requestURL = request.getRequestURL();
System.out.println(requestURI);
System.out.println(requestURL);
//6. 获取协议及版本:HTTP/1.1
String protocol = request.getProtocol();
System.out.println(protocol);
//7. 获取客户机的IP地址:
String remoteAddr = request.getRemoteAddr();
System.out.println(remoteAddr);
}
获取请求头数据方法代码演示:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//演示获取请求头数据
//1.获取所有请求头名称
Enumeration<String> headerNames = request.getHeaderNames();
//2.遍历
while(headerNames.hasMoreElements()){
String name = headerNames.nextElement();
//根据名称获取请求头的值
String value = request.getHeader(name);
System.out.println(name+"---"+value);
}
}
//------------------通过获取请求头referer数据防盗链-----------------------
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//演示获取请求头数据:referer
String referer = request.getHeader("referer");
System.out.println(referer);//http://localhost/day14/login.html
//防盗链
if(referer != null ){
if(referer.contains("/day14")){
//正常访问
// System.out.println("播放电影....");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("播放电影....");
}else{
//盗链
//System.out.println("想看电影吗?来优酷吧...");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write("想看电影吗?来优酷吧...");
}
}
}
获取请求体数据方法代码演示:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求消息体--请求参数
//1.获取字符流
BufferedReader br = request.getReader();
//2.读取数据
String line = null;
while((line = br.readLine()) != null){
System.out.println(line); // username=zhangsan&password=123
}
}
获取请求参数通用方式代码演示:
public class RequestDemo6 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//post 获取请求参数
//根据参数名称获取参数值
String username = request.getParameter("username");
//根据参数名称获取参数值的数组
String[] hobbies = request.getParameterValues("hobby");
for (String hobby : hobbies) {
System.out.println(hobby);
}
//获取所有请求的参数名称
Enumeration<String> parameterNames = request.getParameterNames();
while(parameterNames.hasMoreElements()){
String name = parameterNames.nextElement();
System.out.println(name);
String value = request.getParameter(name);
System.out.println(value);
System.out.println("----------------");
}
// 获取所有参数的map集合
Map<String, String[]> parameterMap = request.getParameterMap();
//遍历
Set<String> keyset = parameterMap.keySet();
for (String name : keyset) {
//获取键获取值
String[] values = parameterMap.get(name);
System.out.println(name);
for (String value : values) {
System.out.println(value);
}
System.out.println("-----------------");
}
}
}
请求转发和共享数据方法代码演示:
@WebServlet("/requestDemo8")
public class RequestDemo8 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo8888被访问了。。。");
//转发到demo9资源
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/requestDemo9");
requestDispatcher.forward(request,response);
//存储数据到request域中
request.setAttribute("msg","hello");
//链式编程
request.getRequestDispatcher("/requestDemo9").forward(request,response);
}
}
@WebServlet("/requestDemo9")
public class RequestDemo9 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取数据
Object msg = request.getAttribute("msg");
System.out.println(msg);
System.out.println("demo9999被访问了。。。");
}
3. 通过连接数据库 来 验证登录用户名和密码 是否正确( 综合Request知识点 )
步骤:
1. 创建数据库并导入jia包 和 数据库连接池配置文件 durid.properties
2. 创建user对象并在web包下创建 login.html页面
3. 创建 JDBCUnit工具类
4. 创建类,类中定义执行 sql语句返回 user对象的方法
5.
@WebServlet("/curry") /* 一定要注意加这个@WebServlet 不然部署工件出错 */
public class loginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 根据参数名称(from表单里面的name属性)获取值
String username = req.getParameter("username");
String password = req.getParameter("password");
//2.创建user对象用于与数据库查询出来的对象进行比较
user loginUser = new user();
loginUser.setUsername(username);
loginUser.setPassword(password);
// 第2步封装对象用 BeanUtils工具类更加简便 导包时候注意 导入 apache的
Map<String, String[]> map = req.getParameterMap();//获取所有参数的键值对集合
user loginUser = new user();
//populate(Object obj , Map map):将map集合的键值对信息,封装到对应的JavaBean对象中
try {
BeanUtils.populate(loginUser,map);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
//3.创建 loginJDBCTemplate 对象调用方法查询
loginJDBCTemplate user = new loginJDBCTemplate();
user rsUser = user.login(loginUser);
//4.根据返回值判断进入不同页面
if (rsUser == null){
//4.1 根据用户输入的用户名和密码未查询到,然后请求转发
req.getRequestDispatcher("/fail").forward(req,resp);
}else {
//4.2 查询到后存储数据
req.setAttribute("user",rsUser);
req.getRequestDispatcher("/success").forward(req,resp);
}
}
}
6. 查询成功请求转发到这里
@WebServlet("/success")
public class SuccessServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
user user = (user)req.getAttribute("user");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("成功"+user.getUsername());
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
7. 查询失败请求转发到这里
@WebServlet("/fail")
public class failServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
resp.getWriter().write("sbai");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
}
二. Response对象
1. 功能
2. 知识点
1.重定向和转发的区别
2. 路径写法
3. 案例
① 简单重定向
@WebServlet("/responseDemo1")
public class ResponseDemo1 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo1........");
// 要求:访问/responseDemo1,会自动跳转到/responseDemo2资源
// 1.设置状态码为302
response.setStatus(302);
//2.设置响应头location
response.setHeader("location","/day15/responseDemo2");
//简单的重定向方法
String contextPath = request.getContextPath();
response.sendRedirect(contextPath+"/responseDemo2");
//访问其他站点
//response.sendRedirect("http://www.itcast.cn");
}
2. 服务器输出字符和字节数据到浏览器
//输出字符到浏览器
@WebServlet("/responseDemo4")
public class ResponseDemo4 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//简单的形式,设置编码
response.setContentType("text/html;charset=utf-8");
//1.获取字符输出流
PrintWriter pw = response.getWriter();
//2.输出数据
//pw.write("<h1>hello response</h1>");
pw.write("你好啊啊啊 response");
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
//输出字节到浏览器
@WebServlet("/responseDemo5")
public class ResponseDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
//1.获取字节输出流
ServletOutputStream sos = response.getOutputStream();
//2.输出数据
sos.write("你好".getBytes("utf-8"));
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
3. 点击切换图片验证码
@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int width = 100;
int height = 50;
//1.创建一对象,在内存中图片(验证码图片对象)
BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
//2.美化图片
//2.1 填充背景色
Graphics g = image.getGraphics();//画笔对象
g.setColor(Color.PINK);//设置画笔颜色
g.fillRect(0,0,width,height);
//2.2画边框
g.setColor(Color.BLUE);
g.drawRect(0,0,width - 1,height - 1);
String str = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghigklmnopqrstuvwxyz0123456789";
//生成随机角标
Random ran = new Random();
for (int i = 1; i <= 4; i++) {
int index = ran.nextInt(str.length());
//获取字符
char ch = str.charAt(index);//随机字符
//2.3写验证码
g.drawString(ch+"",width/5*i,height/2);
}
//2.4画干扰线
g.setColor(Color.GREEN);
//随机生成坐标点
for (int i = 0; i < 10; i++) {
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);
}
//3.将图片输出到页面展示
ImageIO.write(image,"jpg",response.getOutputStream());
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request,response);
}
}
四 . BeanUtils工具类,简化数据封装
代码演示:
4 . ServletContext对象
1. 概念&获取对象
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
ServletContext servletContext1 = request.getServletContext();
}
2. 功能(获取MIME类型_域对象_真实服务路径)
代码演示:
@WebServlet("/servletContextDemo2")
public class ServletContextDemo2 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//2. 通过HttpServlet获取
ServletContext context = this.getServletContext();
//3. 定义文件名称
String filename = "a.jpg";
//4.获取MIME类型
String mimeType = context.getMimeType(filename);
System.out.println(mimeType);//image/jpeg
}
@WebServlet("/servletContextDemo5")
public class ServletContextDemo5 extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 通过HttpServlet获取
ServletContext context = this.getServletContext();
// 获取文件的服务器路径
String b = context.getRealPath("/b.txt");//web目录下资源访问
System.out.println(b);
// File file = new File(realPath);
String c = context.getRealPath("/WEB-INF/c.txt");//WEB-INF目录下的资源访问
System.out.println(c);
String a = context.getRealPath("/WEB-INF/classes/a.txt");//src目录下的资源访问
System.out.println(a);
}
3. 文件下载案例(Response_ServletContext)
@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 = this.getServletContext();
String realPath = servletContext.getRealPath("/img/" + filename);
//2.2用字节流关联
FileInputStream fis = new FileInputStream(realPath);
//3.设置response的响应头
//3.1设置响应头类型:content-type
String mimeType = servletContext.getMimeType(filename);//获取文件的mime类型
response.setHeader("content-type",mimeType);
//解决中文文件名问题
//3.2.获取user-agent请求头、
String agent = request.getHeader("user-agent");
//3.3.使用工具类方法编码文件名即可
filename = DownLoadUtils.getFileName(agent, filename);
//3.4.设置响应头打开方式:content-disposition
response.setHeader("content-disposition","attachment;filename="+filename);
//4.将输入流的数据写出到输出流中
ServletOutputStream sos = response.getOutputStream();
byte[] buff = new byte[1024 * 8];
int len = 0;
while((len = fis.read(buff)) != -1){
sos.write(buff,0,len);
}
fis.close();
}