Servelet
Servelet1. 数据库和浏览器的交互servlet获取前端页面中的数据servlet 将数据传入dao层Dao层把数据存储到数据库数据库将反馈结构传送给dao层Dao层将结果给servletservlet把得到的结果展示再浏览器上2. What is ServletServlet是服务器端的小程序,是tomcat的核心组件,可以获取客户端的请求信息,也可以给客户端响应信息。狭义上的概念:ja
Servelet
1. 数据库和浏览器的交互
- servlet获取前端页面中的数据
- servlet 将数据传入dao层
- Dao层把数据存储到数据库
- 数据库将反馈结构传送给dao层
- Dao层将结果给servlet
- servlet把得到的结果展示再浏览器上
2. What is Servlet
- Servlet是服务器端的小程序,是tomcat的核心组件,可以获取客户端的请求信息,也可以给客户端响应信息。
- 狭义上的概念:javax.servlet.Servlet接口及其子接口都属于servlet
- 广义上的概念:servlet接口的实现类都属于servlet
3. Servlet 原始部署步骤
1) 实现Servlet接口
package com.wy.Day11_Practice;
import javax.servlet.*;
import java.io.IOException;
/**
* @author HelloWorld
* @create 2021-05-24-20:07
* @email 154803771@qq.com
*/
public class Hello implements Servlet {
// 初始化方法
@Override
public void init(ServletConfig config) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
// 处理客户端请求
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
}
@Override
public String getServletInfo() {
return null;
}
// 销毁servlet
@Override
public void destroy() {
}
}
2) 在web.xml注册servlet
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<!--servlet名称,和servlet的类名保持一致-->
<servlet-name> Hello</servlet-name>
<!-- 设置servlet全类名-->
<servlet-class>com.wy.Day11_Practice.Hello</servlet-class>
</servlet>
<!-- 设置映射地址-->
<servlet-mapping>
<!-- 通过该值映射servlet的名称-->
<servlet-name>Hello</servlet-name>
<!-- 浏览器中的url地址,要加 /-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
3). 在index.jsp中添加 a 标签
<%@ page contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<title>JSP - Hello World</title>
</head>
<body>
<h1><%= "Hello World!" %>
</h1>
<br/>
<a href="hello-servlet"> hello </a>
</body>
</html>
4. Servlet生命周期
- 构造器: 第一次请求servlet调用,创建Servlet实例
- Init(): 初始化方法,第一次请求时被调用,在整个生命周期中只被调用一次
- Service(): 每次被请求都会调用
- Destory(): 销毁时调用
5. Servlet注解
@WebServlet(name = "LoginServlet", value = "/LoginServlet")
or
@WebServlet(name = "LoginServlet", urlPatterns = "/LoginServlet")
<url - pattern> 配置方式
- 绝对路径 => / LoginServlet
- 目录匹配 => / * 匹配目录下的全部内容都可以访问
- 扩展后缀名匹配 => * .action
6. doGet() 和 doPost()
- 请求方式为get 调用doGet()
- 请求方式为post 调用doPost()
get 和 post的区别
- GET在浏览器后退刷新时是无害的,而POST会再次提交请求。
- GET产生的URL地址可以被收藏为书签,而POST不可以。
- GET请求会被浏览器主动cache,而POST不会,除非手动设置。
- GET请求只能进行url编码,而POST支持多种编码方式。
- GET请求参数会被完整保留在浏览器历史记录里,而POST中的参数不会被保留。
- GET请求在URL中传送的参数是有长度限制的,而POST没有。
- 对参数的数据类型,GET只接受ASCII字符,而POST没有限制。
- get 的参数直接展示在URL上,post的数据只会被保存到浏览器历史或服务器日志上
- GET参数通过URL传递,POST放在Request body中。
7. 请求与响应
- HttpServletRequest 请求 => 从浏览器端接收到服务器端
- HttpServlletResponse 响应 => 从服务器端发送到浏览器端
7.1 请求
7.1.1 获取请求行中的数据
获取当前的请求方式
String method = request.getMethod();
获取get请求方式中的用户提交数据
String queryString = request.getQueryString();
7.1.2 获取当前请求路径
获取请求全路径
StringBuffer requestURL = request.getRequestURL();
获取当前请求路径,不包含主机地址
String requestURI = request.getRequestURI();
获取当前项目名称
String contextPath = request.getContextPath();
7.1.3 获取请求头中的数据
获取当前请求头所在页面
String referer = request.getHeader("Referer");
获取User-Agent
String header = request.getHeader("User-Agent");
7.1.4 获取表单中的数据
获取单条信息
String username = request.getParameter("username"); String password = request.getParameter("password"); String hobby = request.getParameter("home");
获取checkbox中的数据
String[] hobbies = request.getParameterValues("hobby");
补充
request.getAttribute(“name”)可得到JSP页面一表单中控件的Value。其实表单控件中的Object的 name与value是存放在一个哈希表中的,所以在这里给出Object的name会到哈希表中找出对应它的value。
而不同页面间传值使用request.setAttribute(key, value)时,只会从a.jsp到b.jsp一次传递,之后这个request就会失去它的作用范围,再传就要再设一个 request.setAttribute()。而使用session.setAttribute(key, value)会在一个过程中始终保有这个值。
7.2 响应
7.2.1 响应普通文本
PrintWriter writer = response.getWriter(); writer.print("寻寻觅觅,凄凄惨惨戚戚");
7.2.2 响应表格
// 解决乱码 charset=utf-8 response.setContentType("text/html;charset=utf-8"); PrintWriter writer = response.getWriter(); // 响应表格 writer.append("<h1>表格<h1>"); writer.append("<table>"); writer.append("<tr>"); writer.append("<th>编号</th>"); writer.append("<th>姓名</th>"); writer.append("<th>性别</th>"); writer.append("<th>地址</th>"); writer.append("</tr>"); writer.append("<tr>"); writer.append("<td>1</th>"); writer.append("<td>wy</th>"); writer.append("<td>男</th>"); writer.append("<td>敖德萨</th>"); writer.append("</tr>"); writer.append("</table>");
7.2.3 响应图片(提供文件下载)
// 1.获取文件路径 String realPath = getServletContext().getRealPath("/static/image/Bg.jpg"); // 2.获取输入流对象 FileInputStream fileInputStream = new FileInputStream(realPath); // 3.获取文件类型 String mimeType = getServletContext().getMimeType(realPath); // 4.将文件类型返回给浏览器 response.setHeader("Content-Type", mimeType); // 文件名要和资源名保持一致 String fileName = "背景.jpg"; // 处理下载中的乱码问题 String header = request.getHeader("User-Agent").toLowerCase(Locale.ROOT); // 火狐的乱码处理 if (header.contains("firefox")) { fileName = new String(fileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1); } else { fileName = URLEncoder.encode(fileName, "utf-8") ; } // 5.让浏览器已下载的方式处理该文件 response.setHeader("Content-Disposition", "attachment; filename="+fileName); // 6.实现下载 ServletOutputStream outputStream = response.getOutputStream(); byte[] datas = new byte[1024]; int len = 0; while ((len = fileInputStream.read(datas)) != -1) { outputStream.write(datas, 0, len); } outputStream.close(); fileInputStream.close();
8. 转发和重定向
转发 :客户端向服务器发送请求,服务器响应转发请求,直接给用户返回跳转界面,一次请求
request.getRequestDispatcher("/LoginSuccessful.html").forward(request, response);
重定向:客户端发送请求,服务器返回客户端302状态码,提供客户端新的访问地址,客户端请求新地址, 两次请求
response.sendRedirect(request.getContextPath() + "/LoginSuccessful.html"); // request.getContextPath() => /当前项目名称,而/又在浏览器中解析,所有会被解析为主机地址,最终就形成了完整的绝对地址
区别
- 转发往服务器发送一次请求,重定向往服务器发送两次请求
- 转发是在服务器内部完成 ,客户感知不到;响应是给客户端302状态码,让客户端去访问新的地址
- 使用转发地址栏不发生变化;使用重定向地址栏发生变化
- 使用转发可以访问WEB-INF下的资源;使用重定向不可以访问WEB-INF下的资源。因为WEB-INF对客户端的请求做了一层隔离,所以说,浏览器直接请求WEB-INF 下的资源是不允许的。
9. 请求响应中的乱码问题
9.1 请求中的乱码
编码与解码
浏览器编码: 浏览器中的编码格式由html中的meta的
====
chart属性值指定,通常为 utf-8
服务器解码:服务器的解码格式为 iso-8859-1
post请求
post请求 在servlet中解码
request.setCharacterEncoding(“utf-8”);
get请求
get请求,由Tomcat解码
Tomcat8 默认解码格式为 utf - 8 不用配置解码格式
Tomcat7 默认解码格式为 iso8859-1 需要在 cof / server.xml 文件中加入 URIEncoding=“utf-8”;
<Connector URIEncoding="utf-8" connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
9.2响应中的乱码
编码与解码
- 服务器编码: 默认格式为 iso-8859-1
- 客户端解码: 默认格式为GBK
response.setContentType("text/html;charset=utf-8");
10. web中的路径问题
- “/” 代表绝对路径
- 由浏览器解析 “/” 代表当前主机地址目录下
- a标签中的href
- scrip标签中的src
- link标签中的href
- form标签中的action
- 重定向,request.getContextPath() 得到的地址 => / 当前项目名称,"/" 表示主机地址
- 由服务器解析 "/ " 代表当前项目名称目录下 包括 https://主机地址 端口号/ 项目名称
- 转发
- servletContext.realPath()
- web.xml文件中的url-pattern标签
- base 标签
- 浏览器的地址在发送请求时会在地址前加上base标签中的href的属性值
11. 反射机制处理多方法请求
<form action="UserServlet03?way=doLogin" method="post">
- 提交方式只能为post
将反射机制封装在Base工具类
@WebServlet(name = "BaseServlet", value = "/BaseServlet") public class BaseServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 1.设置编码为utf-8 request.setCharacterEncoding("utf-8"); // 2.获取请求中的way的属性值 String way = request.getParameter("way"); // 3.通过反射获取对应的方法 Method method = null; try { method = this.getClass().getDeclaredMethod(way, HttpServletRequest.class, HttpServletResponse.class); } catch (NoSuchMethodException e) { e.printStackTrace(); } // 获取具有protected属性方法的访问权 assert method != null; method.setAccessible(true); // 使用方法 try { method.invoke(this, request, response); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } }
UserServlet继承Base工具类
@WebServlet(name = "UserServlet03", value = "/UserServlet03") public class UserServlet extends BaseServlet{ protected void doLogin(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); System.out.println(username); System.out.println(password); response.sendRedirect(request.getContextPath() + "/success.html"); } protected void doRegister(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); String username = request.getParameter("username"); String password = request.getParameter("password"); String sex = request.getParameter("sex"); String email = request.getParameter("email"); System.out.println(""); request.getRequestDispatcher("/success.html").forward(request, response); }
12. 杀掉某一端口对应的进程
- 查看计算机中所有进程 netstat -nao
- 找到某端口对应的进程的PID
- taskkill /pid 具体pid值 /f
优化版
查看被占用端口对应的 PID
输入命令:
netstat -aon|findstr “8081”
结束进程
强制(/F参数)杀死 pid 为 9088 的所有进程包括子进程(/T参数):taskkill /T /F /PID 9088
更多推荐
所有评论(0)