Tomcat
web应用服务器:Tomcat
web架构:客户端连接服务器,服务器当中部署web应用服务器,以及一系列Java程序
客户端通过Tomcat访问服务器中的Java程序
Tomcat文件夹
bin:存放各个平台下启动和停止Tomcat服务的脚本
conf:存放各种Tomcat服务器的配置文件
存放不同的端口,serve.xml
lib:存放Tomcat服务运行需要的jar
logs:存放Tomcat运行日志
temp:Tomcat运行的临时文件
webApps:存放用户客户端访问的资源(Java程序)
将程序放在文件夹中启动Tomcat客户端即可访问其中的文件
work:存放Tomcat将JSP转换之后的Servlet文件
URL
IP地址:指的是服务器所在的IP地址
PORT:服务器所提供访问的端口
PN:application当中部署的应用
在IDEA中通过设置Tomcat的deployment
Servlet
- 什么是Servlet
Servlet是Java web开发的基石,与平台无关(操作系统)的服务器组件,运行在Servlet容器/Web应用服务器/Tomcat,负责和客户端进行通信
创建并返回基于客户请求的动态HTML页面
与数据库进行通信
Servlet可以使用JDBC,成为连接后端和数据库的桥梁
- 怎样使用Servlet
本质上:Servlet是一组接口,储存在javax.servlet包当中
javax是java包的扩展
package com.eric.servlet;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
import java.io.Writer;
import java.util.Enumeration;
public class MyServlet implements Servlet {
public MyServlet(){
System.out.println("constructing");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println(servletConfig.getServletName());
System.out.println(servletConfig.getInitParameter("username"));
Enumeration<String> enumeration = servletConfig.getInitParameterNames();
while (enumeration.hasMoreElements()){
String element = enumeration.nextElement();
System.out.println("name:" + element + " value:" + servletConfig.getInitParameter(element));
}
ServletContext servletContext = servletConfig.getServletContext();
System.out.println(servletContext.getContextPath());
System.out.println(servletContext.getServerInfo());
System.out.println(servletContext.getServletContextName());
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("我是servlet,已接受");
servletResponse.setContentType("text/html;charset=UTF-8");
Writer writer = servletResponse.getWriter();
writer.write("你好");
String id = servletRequest.getParameter("id");
System.out.println("id = " + id);
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
- 创建Servlet
先行创建包,在创建.java文件(在src文件夹中)
- 创建映射
浏览器只能访问到web-inf文件夹中的文件,无法直接访问src中的servlet,需要进行映射
- 通过XML文件配置的方式
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>com.eric.servlet.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/myservlet</url-pattern>
</servlet-mapping>
servlet-name:用于servlet和servlet-mapping映射
servlet-class:指servlet带包文件名
url-pattern:指位于浏览器url之后的内容
- 基于注解的方式
@WebServlet("/myservlet")
Servlet的生命周期
-
当浏览器访问Servlet的时候,Tomcat会查询当前Servlet的实例化对象是否已经存在,不存在则通过反射机制(不需要main方法)利用无参数构造函数创建对象,存在则执行第三步
-
调用init方法完成初始化操作
参数servletConfig:用于描述Servlet的基本信息
getServletName()返回Servlet的名称(全类名)
getInitParameter(String key)获取init参数的值(位于web.xml)
<servlet> <servlet-name>myServlet</servlet-name> <!--给一个servlet标签对应起类当中的语句(指向服务器)--> <servlet-class>com.eric.servlet.MyServlet</servlet-class> <init-param> <param-name>username</param-name> <param-value>admin</param-value> </init-param> <init-param> <param-name>password</param-name> <param-value>123123</param-value> </init-param> </servlet>
getINitParaNames()返回所有initParameter的name值
getServletContext()返回servletContext对象,是servlet的上下文
Servlet层次结构
Servlet(顶端接口) —》 GenericServlet —》 HttpServlet(是子类不是接口)
servlet开发往往是直接继承HTTPservlet,只需要覆写两个方法:doGet,doPost(分别是浏览器读取和保存)
httpservlet实现方法:先创建实现servlet,再创建一个类继承该类,只重写service(通过getmethod方法获取请求类型)
Http请求类型
GET:从数据库读取数据[a标签发出的请求都是get请求]
POST:让数据库保存数据(即添加信息)
PUT:修改数据
DELETE:删除数据
直接继承servlet,全部在service方法实现,继承httpservlet会自动分类
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("/test")
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("get");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter().write("post");
}
}
JSP(HTML+CSS+JS+JAVA)
JSP在本质上就是servlet(处理客户端的请求):主要负责与用户进行交互,将最终的界面呈现给用户
JSP的作用是既能返回页面,也能处理数据
运作:当服务器接收到jsp请求时,将请求交给JSP引擎,每一个jsp页面第一次被访问,jsp引擎将会翻译成servlet文件,再有web服务器进行调用 – 相当于让一个httpservlet不停的write html代码
如何用servlet返回一个HTML页面(writer返回的只是文本,不是页面)
- 直接用writer一行一行返回html文本
- 直接返回jsp文件的位置
JSP文件嵌入Java代码
- JSP脚本嵌入
<%
String string = "helloworld";
System.out.println(string);
%>
- JSP声明:定义Java方法
<%!
public void say(){
System.out.println("helloworld");
}
%>
- JSP表达式:Java对象直接输出到HTML页面
<%
String str = "12";
%>
<%=str%>
JSP内置对象(9个在JSP文件当中可以直接进行调用)[常用的:request,response,session,application,pageContext]
-
request:表示一次请求(HttpServletRequest)[请求完毕自动销毁]
String getParameter(String key) : 获取客户端浏览器获取的参数
void setAttribute(String key,Object value) : 通过键值对的形式保存数据(服务器内部页面传输)
Object getAttribute(String key):通过key取出value
requestDispatcher getRequestDispatcher(String path):转发数据到其他的jsp页面,同时浏览器跳转到下一页面
requestDispatcher的forward方法发送请求
String[] getParameterValues():获取客户端传来的多个同名参数
setCharacterEncoding(String key):设置编码(防止中文乱码)
-
response:表示一次相应(HttpServletResponse)
sendRedirect(string path):将请求从一个页面传递到另一个页面
和setattribute的区别是它会创建一个新的请求(无法通过request的getattribute获取),需要有客户端发送一次新的请求,会跳转页面[如果页面需要传值,必须使用转发]
例子:用户登录,用户名密码正确,跳转到首页,并展示用户名(转发),否则跳转回到登陆界面(重定向)[是一种单纯的跳转]
jsp文件当中的input标签可以用于参数的传递,用getparameter获取,参数为input标签的name属性
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; @WebServlet("/login") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("email"); String password = req.getParameter("password"); if(name.equals("894962134@qq.com") && password.equals("123")){ req.setAttribute("name", name); req.getRequestDispatcher("index.jsp").forward(req, resp); } else{ String mistake = "mistake"; req.setAttribute("mistake", mistake); req.getRequestDispatcher("login.jsp").forward(req, resp); } } }
问题:request的生命周期太短,刷新就会出现问题(用session存储)
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 javax.servlet.http.HttpSession; import java.io.IOException; @WebServlet("/login") public class LoginServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String name = req.getParameter("email"); String password = req.getParameter("password"); HttpSession session = req.getSession(); if(name.equals("894962134@qq.com") && password.equals("123")){ session.setAttribute("name", name); //用session存储只要浏览器不关闭就不会清除信息 req.getRequestDispatcher("index.jsp").forward(req, resp); } else{ String mistake = "mistake"; session.setAttribute("mistake", mistake); req.getRequestDispatcher("login.jsp").forward(req, resp); } } }
-
pageContext:页面信息(pageContext)
-
session:表示一次会话,从打开浏览器到关闭浏览器,一次会话有很多个请求和相应(HttpSession)
用户会话:一个网站会有很多的终端同时访问,而服务器无法识别每一次HTTP请求的出处,出现的问题:将用户的相应发送给其他人
会话:一台服务器和终端发生的一系列请求以及响应(打开浏览器到关闭浏览器)
会话状态:借助会话状态,服务器把属于同一次会话的请求和响应进行连接[属于同一个会话的请求都有同一个sessionID]
String sessionID = session.getId();
实现会话的方法:session(Java程序)和cookie(浏览器提供)
session 的方法
- string getID():获取到当前的sessionID
- void setMaxInactiveInterval(int interval):设置是session的时效时间,参数是时间(在一个时间内免登录)
- int getInactiveInterval() : 获取时效时间
- void invalidate():设置session立即失效(退出登录)
- void setAttribute():通过键值对存储数据
- Object getAttribute(String key):通过键值对获取对应数据
- void removeAttribute(String key):删除对应键值对
-
application:表示当前的web应用,保存所有用户共享信息(servletContext)
-
config:当前JSP对应的servlet的servletConfig,获取当前servlet的信息
-
out:向客户端(浏览器)输出数据(JSPWriter)
-
page:当前JSP对应的servlet
-
exception:JSP页面发生的异常
网页异常
-
200:正常
-
404:资源找不到
-
400:请求类型不匹配
-
500:Java程序抛出异常
Cookie
cookie保存在客户端:cookie会跟着请求带到服务端进行操作,然后跟着相应被带回客户端
比如说一台电脑登陆一次之后就不需要重新输入(在同一种浏览器)
-
创建Cookie
Cookie cookie = new Cookie("name", "zhangsan"); response.addCookie(cookie); //通过响应进行返回客户端
-
读取Cookie
Cookie[] cookies = request.getCookies(); for(Cookie cookie2: cookies){ System.out.println(cookie2.toString()); }
Cookie的常用方法
- void setMaxAge(int age):设置Cookie的有效时间
- int getMaxAge():获取有效时间
- String getName():获取Cookie的name值
- String getValue():获取Cookie的value
Session和Cookie之间的区别
session保存在服务器,Cookie保存在客户端
session保存的是object类型,Cookie只能保存文本
session会随着会话的结束(浏览器关闭)而销毁,Cookie可以长期保存[需要设置生命周期]cookie.setMaxAge(1800);
cookie保存相对安全的信息(比如电影观看进度等)
loginServlet.java //添加账户到cookie
Cookie cookie = new Cookie("email", name);
cookie.setMaxAge(1800);
resp.addCookie(cookie);
resp.sendRedirect("account.jsp");
index.jsp <!--主页调取cookie,并自动跳转到用户首页-->
<%
Cookie[] cookies = request.getCookies();
for(Cookie cookie:cookies){
System.out.println(cookie.getName()+" "+cookie.getValue());
if(cookie.getName().equals("email")) {
request.setAttribute("email", cookie.getValue());
request.getRequestDispatcher("account.jsp").forward(request, response);
break;
}
}
%>
account.jsp <!--用户首页获取Cookie-->
<%String email = (String)request.getAttribute("email");%>
logout.java
for(Cookie cookie:cookies){
if(cookie.getName().equals("email")){
cookie.setMaxAge(0); //每一次对cookie做了操作之后都需addcookie
resp.addCookie(cookie);
}
}
JSP数据传输内置对象的作用域(Cookie不属于内置对象,生命周期自定)
page,request,session,application(这四个内置对象都可以通过setAttribution和getAttribution来传输数据)
page < request < session < application
-
page作用域(对应的内置对象是pageContext):只在当前页面有效(jsp内部数据传输)
-
request作用域:在一次请求内部有效(同一个request可以取出数据)
-
session作用域:同一次会话内部有效(同一次打开浏览器)
-
application作用域:整个Web应用内部(Tomcat不关闭就有效)
可以用于访问量的记录
EL表达式(expression language表达式语言)
EL语句只能和jsp标签进行穿插使用,不能写在Java代码当中
替代JSP页面中数据访问的复杂编码:${变量名}
变量名称是存储在键值对中的名字,只简化了接受语法,没有简化发送语法
EL表达式可以取上述四个内置对象存储的键值对的值
同名的情况默认优先级:page > request > session > application(和作用域大小正好相反)
指定作用域进行查找(${作用域Scope.变量名})
- pageContext:${pageScope.name}
- request:${request.name}
- session:${session.name}
- qpplication:${application.name}
El可以展示(赋值)类对象以及其属性,直接级联就可以[实体类方法需要有共有的get,set方法]
${user.id}
${user.id = 3}
EL展示的信息不一定就是属性的值,是get方法返回的值
EL语句发送object
- 发送的语法并没有发生改变
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.ArrayList;
@WebServlet("/list")
public class List extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ArrayList<Employee> list = new ArrayList<>();
list.add(new Employee(12, "asd","dehu"));
list.add(new Employee(12, "asd","dehu"));
list.add(new Employee(12, "asd","dehu"));
req.setAttribute("list", list);
req.getRequestDispatcher("index.jsp").forward(req, resp);
}
}
- 展示时如果是集合类不能调用方法(利用的是反射机制)
<table>
<thead>
<td>name</td>
<td>id</td>
<td>address</td>
</thead>
<tr>
<td>${requestScope.list[0].name}</td>
<td>${requestScope.list[0].id}</td>
<td>${requestScope.list[0].address}</td>
</tr>
</table>
JSTL详解
JSP Standard Tag Library:JSP标准标签库,JSP为开发者提供的标签,用来完成逻辑处理(循环等),取代JSP脚本穿插,用于展示传输的数据
JSTL侧重于逻辑处理,EL用于展示数据
JSTL 使用
-
导入JSTL.jar和standard.jar(必须存放在WEB-INF)
-
在JSP页面开始端,配置引用
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
-
在需要的页面区域进行使用
<c:forEach items="${requestScope.list}" var="employee">
<tr>
<td>${employee.name}</td>
<td>${employee.id}</td>
<td>${employee.address}</td>
</tr>
</c:forEach>
常用标签
-
set
向域对象当中添加数据和以下脚本相等
<% request.setAttribute(key,value); %>
<c:set var="name" value="tom" scope="request"></c:set>
-
out
输出域对象中的数据
<c:out value="${name}" default="未定义"></c:out>
-
catch(用于捕获异常)
<c:catch var="error"> <%int a = 10/0;%> </c:catch> ${error}
-
条件标签:if choose
<c:if test="${num1>num2}">ok</c:if> <c:if test="${num1<num2}">fail</c:if>
<c:choose> <c:when test="${num1>num2}">ok</c:when> <c:otherwise>fail</c:otherwise> </c:choose>
-
迭代标签 foreach
<c:forEach items="${requestScope.list}" var="employee"> <tr> <td>${employee.name}</td> <td>${employee.id}</td> <td>${employee.address}</td> </tr> </c:forEach>
item: 需要迭代的集合类
begin: 开始的元素
<c:forEach items="${requestScope.list}" var="employee" begin="2">
end: 结束的元素
<c:forEach items="${requestScope.list}" var="employee" end="2">
step: 每一次迭代的步数
<c:forEach items="${requestScope.list}" var="employee" step="2">
varStatus: 用来取集合中元素的信息
<c:forEach items="${requestScope.list}" var="employee" varStatus="sta"> ${sta.count} <br/> </c:forEach>
格式化标签库(对日期,时间等的处理)
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%request.setAttribute("date",new Date());%>
<fmt:formatDate value="${date}" pattern="yyyy-MM-dd HH:mm:ss"></fmt:formatDate>
<fmt:formatNumber value="234567.1233" maxIntegerDigits="2" maxFractionDigits="3"></fmt:formatNumber>
</body>
</html>
函数标签库
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%request.setAttribute("str","java");%>
${fn:contains(str,"python")}
${fn:startsWith(str,"java")}
${fn:endsWith(str, "a")}
${fn:indexOf(str, "va")} <!-- 判断字符串存在的位置-->
${fn:replace(str, "a", "c")}
${fn:split(str, "a")}
${fn:substring(str, 2, 3)} <!-- 截取字符串-->
</body>
</html>
Filter 过滤器(位于服务端和客户端之间)
对不满足规范的请求进行过滤,将某些重复的请求进行处理,或者直接截断请求
修改或者以某种方式处理客户端和服务端之间的数据流:比如设置编码方式
Filter 是 java web 提供的接口,只需要创建一个类再实现该接口即可
实现filter接口可以只实现doFilter方法,其他的方法是default
package com.Eric.filter;
import javax.servlet.*;
import java.io.IOException;
public class CharacterFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("UTF-8"); //所有的请求均设置编码方式为UTF-8
filterChain.doFilter(servletRequest, servletResponse); //和键值对的转发类似,必须添加
}
}
配置filter映射
<?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">
<filter>
<filter-name>character</filter-name>
<filter-class>com.Eric.filter.CharacterFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>character</filter-name>
<url-pattern>/login</url-pattern>
<url-pattern>/register</url-pattern> <!--一个filter可以截留多个servlet-->
</filter-mapping>
</web-app>
filter的生命周期
filter和servlet基本相同(除了实例化对象的时间点不同):以目的地为分类
- 当Tomcat启动时,通过反射机制调用无参数构造创建实例化对象,同时调用init方法实现初始化
- 访问一次filter会调用一次dofilter方法
- 当Tomcat关闭的时候会调用destroy方法来销毁filter对象
filter之间的顺序由web xml的配置顺序决定
注解的形式配置(多个映射)
@WebFilter({"/register", "/login"})
主要作用
-
统一处理中文乱码
-
屏蔽(替换)敏感词
package com.Eric.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.IOException; @WebFilter({"/register", "/login"}) public class CharacterFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { String source = servletRequest.getParameter("source"); source = source.replace("敏感词", "***"); servletRequest.setAttribute("source",source); //在servlet当中需要getAttribute(),相当于在重置键值对 filterChain.doFilter(servletRequest, servletResponse); } }
-
控制资源的访问权限(只有登录之后才能访问)
package com.Eric.filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebFilter("/services.jsp") //jsp不需要进行映射 public class LoginPowerFilter implements Filter { @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; HttpSession session = request.getSession(); String email = (String)session.getAttribute("login_email_to_account"); if(email == null) response.sendRedirect("login.jsp"); else filterChain.doFilter(servletRequest, servletResponse); } }
文件上传下载
文件的上传
JSP:
- 设置input标签type为file
- form 的method设置为post(设置为get的话会把文件名传输)
- form表单的enctype属性设置为mutipart/form-data:以二进制的形式传输数据
servlet:
-
fileupload组件:导入commons-fileupload.jar和commons-io.jar
将所有的请求信息解析成FileItem对象,对这个对象操作可以完成上传
fileupload会把一个form表单当中的所有input框全部转换成fileitem对象
package com.Eric.servlet; import com.Eric.Vulnerability; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItem; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletSecurityElement; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.List; @WebServlet("/upload") public class UploadServlet extends HttpServlet { @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { DiskFileItemFactory fileItemFactory = new DiskFileItemFactory(); //文件对象的工厂 ServletFileUpload servletFileUpload = new ServletFileUpload(fileItemFactory); //创建fileupload对象 Vulnerability vul = new Vulnerability(); try { List<FileItem> list = servletFileUpload.parseRequest(req); //直接获取上传文件的fileitem对象的集合 for(FileItem fileItem:list){ //判断表单当中提交的是文件还是文本 if(fileItem.isFormField()){ if (fileItem.getFieldName().equals("name")) vul.setName(fileItem.getString("UTF-8")); else if (fileItem.getFieldName().equals("message")) vul.setMessage(fileItem.getString("UTF-8")); else vul.setCatagory(fileItem.getString("UTF-8")); }else{ String filename = fileItem.getName(); vul.setFilename(filename); InputStream inputStream = fileItem.getInputStream(); String path = req.getServletContext().getRealPath("FILE/" + filename); OutputStream outputStream = new FileOutputStream(path); int temp = 0; while((temp=inputStream.read()) != -1){ outputStream.write(temp); } outputStream.close(); inputStream.close(); //连接数据库之后导入vul } } } catch (FileUploadException e) { e.printStackTrace(); } } }
文件下载
下载属于响应,调用response
package com.Eric.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.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@WebServlet("/kitdownload")
public class KitDownload extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//启动下载器,响应方式的设置
resp.setContentType("application/x-msdownload");
//设置下载之后的文件名
String filename = "kit.pdf";
resp.setHeader("Content-Disposition", "attachment;filename=" + filename);
OutputStream outputStream = resp.getOutputStream();
String path = req.getServletContext().getRealPath("FILE/kti.pdf");
InputStream inputStream = new FileInputStream(path);
int temp = 0;
while((temp = inputStream.read())!=-1){
outputStream.write(temp);
}
outputStream.close();
inputStream.close();
}
}
Ajax
Asynchronous JavaScript And Xml (异步的js和XML)
指的是交互方式:异步加载:客户端与服务器的数据交互是更新在局部页面,不需要刷新整个页面
优点:效率更高,用户体验更好:页面的需求分成两个步骤,同步加载会导致后面的步骤白费
传统响应方式:响应一个完整的页面,AJax:只返回需要的数据
基于JQuery的Ajax
<script type="text/javascript" src="js/jquery-3.4.1.min.js"></script>
<!--jsp代码-->
<script>
$(function () {
var btn = $("#frontPage"); //获取一个按钮对象,使用id选择器
btn.click(function () { //监听点击事件
$.ajax({
url:'/frontPage',
type:'post',
dataType:'text',
data:'id=1', //传递的参数
success:function (data) { //服务器返回的数据:data
var table = $("#table");
table.before("<span>" + data + "</span>");
}
});
});
})
</script>
package com.Eric.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;
@WebServlet("/frontPage")
public class FrontPageServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
String string = "hello";
resp.getWriter().write(string); //只给页面返回一个数据,返回给ajax
//不能跳转到jsp,只能返回数据,否则会页面重新加载
}
}
Ajax基本语法
$.ajax({属性})
- url:请求的后端服务地址
- type:请求的类型(默认是get方式)
- data:请求的参数
- datatype:服务器返回的数据类型:text/json
- success:请求成功的回调函数:执行到页面的动作
- error:请求失败的回调函数
- complete:请求完成的回调函数,先进入complete再进入success
JSON
JavaScript object notation:在js当中描述对象,完成js与Java的对象数据转换,将Java对象封装成JSON
服务器和客户端交互数据出现对象类型数据
<script>
$(function () {
var btn = $("#frontPage");
btn.click(function () {
$.ajax({
url:'/frontPage',
type:'post',
dataType:'json',
data:'${requestScope.round}',
success:function (data) {
var tbody = $("#body");
$("#vul_id").val(data.name);
}
});
});
})
</script>
package com.Eric.servlet;
import com.Eric.Vul_text;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
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("/frontPage")
class User{
int id;
String name;
public User(int id, String name) {
this.id = id;
this.name = name;
}
}
public class FrontPageServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
User list = new User(1, "hh");
String id = req.getParameter("id");
String string = "hello";
//将Java对象转换成json,再进行返回
JSONObject object = JSONObject.fromObject(list); //将Java对象转换为json对象
resp.getWriter().write(object.toString()); //将json对象返回给ajax
}
}
JDBC:Java database connectivity
是一个独立于特定数据库的管理系统:能够连接各种数据库,通用的SQL数据库存取和操作的公共接口
为访问不同数据库提供了同一途径
JDBC体系结构
- 面向应用的API,供开发者调用
- 面向数据库的API,供数据库产商开发所用
JDBC API:供开发者调用的接口
在java.sql和javax.sql包当中
DriverManager类
由Java官方提供,管理不同的JDBC驱动(由数据库厂商进行提供,负责连接不同的数据库)
Connection接口
Statement接口
ResultSet接口
JDBC的使用
- 加载数据库驱动:Java程序和数据库之间的桥梁(是一种基站)[由数据库产商提供]
- 获取connection:Java程序与数据库的一次链接
- 创建Statement对象,由connection产生,执行SQL语句
- 如果需要接受返回值(执行查询语句等),创建ResultSet对象:用于保存Statement执行之后所查询到的结果[如果只是增加,删除等操作,则不需要该对象]
连接数据库
//connect to database
try {
Class.forName("com.mysql.cj.jdbc.Driver"); //获取运行时类
String url = "jdbc:mysql://localhost:3306/webProject?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
//设置访问数据库的位置
String user= "root";
String databasePassword = "123456";
Connection connection = DriverManager.getConnection(url,user,databasePassword);
//利用Drivermanager管理驱动
String sql = "insert into user(email,password,username) values('123456@qq.com','123','eric')";
String selectSQL = "select * from user";
Statement statement = connection.createStatement();
statement.executeUpdate(sql);
ResultSet resultSet = statement.executeQuery(selectSQL);
//查询sql语句使用query,其他更新类型语句使用update,需要resultSet进行接受
while (resultSet.next()){ //next方法会返回一个布尔值,并跳转到下一个获取的对象
String email = resultSet.getString("email");
String password = resultSet.getString("password");
accountArrayList.add(new Account(email, password, null));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}