Tomcat
web应用服务器:Tomcat、Jboos、Weblogic、Jetty
安装Tomcat
- 下载:Apache Tomcat® - Apache Tomcat 10 Software Downloads
- 解压缩:任意位置,不要有中文路径
bin:存放各个平台下的启动和停止tomcat脚本文件
conf:存放tomcat服务器的配置文件(端口在server.XML)
lib:都是jar包。存放tomcat所需要的jar文件
logs:存放tomcat服务运行的日志
temp:存放tomcat运行时的临时文件
webapps:存放允许客户端访问的资源(Java程序)
work:存放tomcat将jsp转换之后的Servlet文件
idea创建一个JavaWeb项目
1、新建工程的时候选择Java Enterprise
2、如果没有上面选项,可直接创建java项目,再改
(4条消息) idea创建一个javaweb项目_idea创建java web项目_熟悉的新风景的博客-CSDN博客
项目集成tomcat
Servlet
servlet是Java web 开发的基石,与平台无关的服务器组件,它运行在Servlet容器/Web应用服务器/Tomcat中,负责与客户端进行通信
Servlet的功能:
- 创建并返回基于客户端请求的动态HTML页面。
- 与数据库进行通信
Servlet的使用:
Servlet本身是一组接口,(接口本身是实现 某种功能 ),自定义一个类并实现servlet接口,这样这个类就具备了接受客户端请求及做出响应的功能。
例如:创建一个类来继承servlet,来实现通信
浏览器是没有办法直接访问servlet的文件,必须通过映射方式来间接访问
1、基于XML文件的配置方式
在web.XML中编写
2、基于注解的方式
Servlet的生命周期
- 当浏览器访问Servlet的时候,Tomcat会查询当前Servlet的实例化对象是否存在,如果不存在则通过反射机制动态
- 调用init方法完成初始化操作
- 调用service方法完成业务逻辑操作
- 关闭tomcat时,会调用destroy方法,释放当前对象所占用的资源
Servlet生命周期方法
- 无参构造函数:只调用一次,创建对象
- init方法:只调用一次,初始化对象
- service方法:调用n次,执行业务方法
- destroy方法:只调用一次,用来卸载对象
ServletConfig
该接口使用来描述Servlet的基本信息
- getServletName()返回Servlet名称,全类名(带着包名)
-
getInitParameter()获取init参数的值(值是配置在web.XML)
-
getInitParameterNames()返回所有的initparamter的name值,一般作用遍历初始化参数值
-
getServletContext()返回ServletContext对象,它是Servlet的上下文,整个Servlet的管理者
ServletConfig和ServletContext的区别
ServletConfig 作用于某个Servlet实例,每个Servlet都有对应的ServletConfig
ServletContext作用于整个web应用,一个web应用对应一个ServletContext,多个Servlet实例对应于一个ServletContext
Servlet的层次结构
Servlet接口下面有 ->GenericServlet,->下面还有HttpServlet。
GenericServlet为我们屏蔽Servlet不常用的方法,只需要重写用用的方法service
HttpServlet继承GenericServlet,根据请求类型分发处理Get进入doGet方法,post进入doPost方法。
通常只需继承HttpServlet。
HTTP请求有多种类型,常用的有4种:GET读取、POST保存、PUT修改、DELETE删除。
JSP
JSP本质上就是一个Servlet,JSP主要负责与用户交互,将最终的页面呈现给用户,HTML(搭建框架)+JS+CSS+JAVA(填充数据)混合的文件
当服务器接收到jsp的请求时,将该请求交JSP引擎去处理,每一个JSP页面第一次访问的时候,JSP引擎会将它翻译成Servlet文件,再由web容器调用servlet完成这个响应。
JSP嵌入方式
- JSP脚本
<% java代码 %>
- JSP声明:定义Java方法
只能声明方法,不能调方法。
<%!
//声明Java方法
%>
- JSP表达式:把Java对象直接输出到HTML页面中
<%=
//输出的Java变量
%>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<h1>这是我的Servlet测试</h1>
<%
ArrayList<User> list = new ArrayList<>();
list.add(new User("张三",12));
list.add(new User("李四",12));
list.add(new User("王五",12));
list.add(new User("老刘",12));
%>
<table>
<tr>
<th>姓名</th>
<th>年龄</th>
</tr>
<%
for (int i = 0; i < list.size(); i++) {
%>
<tr>
<td>
<%=
list.get(i).getName()
%>
</td>
<td><%= list.get(i).getAge()%></td>
</tr>
<%
}
%>
</table>
</body>
</html>
JSP的内置对象
- request:表示一次请求,对象是由HttpServletRequest类产生的
- response:此对象由HttpServletResponse产生的
- pageContext:页面上下文
- session:表示一次会话,保存用户信息,来自HttpSession类产生的
- application:表示当前web应用,全局对象,保存所有用户共享信息,来此ServletContext
- config:当前JSP对应的Servlet的ServletConfig对象,获取当前Servlet的信息
- out:向浏览器输出数据,来自JspWriter类
- page:当前JSP对应的Servlet对象,来自Servlet
- exception:表示JSP页面发生异常,Exception
request常用方法:
- String getParameter(String Key)//获取客户端传来的参数
- void setAttribute(String key,Object value)通过键值对的形式保存数据
- Object getAttribute(String key) 通过key取出value
- RequestDispather getRequestDispatcher(String path)返回一个RequestDispather对象,该对象的forward方法用于转发请求
- String[] getParameterValues() 获取客户端多个同名参数
- void setCharacterEncoding(String charset)指定每个请求的编码
response常用方法
-
sendRedirect(String path) 重定向,页面之间的跳转。重定向是创建一个新的请求传给下一个页面,之前的请求结束生命周期。且重定向是由客户端发送一次新的请求来访问跳转之后目标资源,地址栏改变,也叫客户端跳转。
与上面的request.getRequestDispatcher转发的区别:转发是将同一个请求传个下一各页面,同一个请求在服务器之间传递,地址栏不变,也叫服务器跳转。
如果两个页面之间需要通过request来传值,则必须使用转发,不能使用重定向
例子:用户登录,如果用户名和密码正确,则跳转到首页(转发的形式),并且展示用户名,否则重新回到登录页面(重定向的方式)。
session
用户会话 :服务器无法识别每一次 HTTP请求的来自哪个终端,它只会接受一个请求信号,所以就存在一个问题:将用户的响应请求发送给其他人,必须有一种技术来让服务器知道请求来自哪里,这就是会话技术。
会话:就是浏览器(客户端)和服务器之间发生的一系列连续的请求和响应的过程。打开浏览器进行操作到关闭浏览器的过程。
会话状态:指服务器和浏览器在会话过程中产生的状态信息,借助于会话状态,服务器能够把属于同一次会话的一系列请求和响应关联起来。
实现会话的两种方式:
- session:属于同一次会话的请求都有一个相同的标识符,sessionID
- cookie
session常用的方法:
- String getId() 获取sessionID
- void setMaxInactiveInterval(int interval) 设置session的失效时间。单位为秒
- int getMaxInactiveInterval() 获取当前session的失效时间
- void invalidate() 设置session立即失效
- void setAttribute(String key,Object value) 通过键值对的形式来存储数据
- Object getAttribute(String key) 通过键来获取对应 文件,一旦浏览器保存了某个Cookie,在之后的请求和响应过程中,会将次Cookie来回传递,这样就可以通过Cookie这个载体完成客户端和服务端的数据 交互。
- 创建Cookie
Cookie cookie = new Cookie("name", "zhangsan");
response.addCookie(cookie);
- 读取cookie
Cookie[] cookies = request.getCookies();
for (Cookie cookie1 : cookies) {
out.write(cookie1.getName()+":"+cookie1.getValue()+"<br/>");
}
Cookie常用方法
- void setMaxAge(int age) 设置Cookie的有效时间,单位为秒
- int getMaxAge() 获取Cookie的有效时间
- String getName() 获取Cookie的name
- String getValue() 获取Cookie的value
Session和Cookie的区别
Session:保存到服务器
保存的数据是Object
会随着会话的结束而销毁
保存重要信息
Cookie:保存在浏览器
保存数据是String
可以长期保存在浏览器中,与会话无关
保存不重要的信息
JSP内置对象的作用域
研究page、request、session、application因为它们有setAttribute、getAttribute来存取数据,只是存取数据的范围不一样
page作用域:对应的内置对象是pageContext。page只在当前页面有效
request作用域:对应的内置对象是request。在一次请求内有效
session作用域:对应的内置对象是session。在一次会话内有效
application作用域:对应内置对象application。对应整个web应用有效
page < request < session < application
例:统计网站访问量
<%
Integer count = (Integer) application.getAttribute("count");
if(count== null){
count =1;
}else {
count++;
}
application.setAttribute("count",count);
%>
您目前是第<%=count%>位访客
EL表达式
Expression Language 表达式语言:替代JSP页面中数据访问时的复杂编码。
可以取出域对象(pageContext、request、session、application)中保存数据,前提是一定要先setAttribute,EL就相当于简化了getAttribute
${需要取的变量名}变量名是setAtrribute对应的key值
1、EL对于4种域对象默认查找顺序
pageContext > request > session > application
按照上述顺序进行查找,找到立即返回,在application中无法找到,则返回null
2、EL指定作用域查找
pageContext:${pageScope.name}
request : ${requestScope.name}
session :${sessionScope.name}
application : ${applicationScope.name}
3、EL执行表达式
- && and
- || or
- ! not
- == eq
- != ne
- < lt
- > gt
- <= le
- >= ge
- empty 变量为null,长度为0的String,size为0的集合
JSTL
JSP Standard Tag Library jsp标准标签库为开发者提供一系列的标签,使用这些标签可以完成逻辑处理,比如:循环遍历集合,让代码更简洁,不再出现JSP脚本穿插的情况
实际开发中EL和JSTL结合使用,JSTL侧重于逻辑处理,EL负责展示数据
JSTL的使用
- 需要导入jar包(jstl.jar standard.jar)
- 在JSP页面开始的地方导入JSTL标签库
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
- 在需要的地方使用
过滤器(Filter)
Filter的功能:
1、用来拦截传入的请求和传出的响应
2、修改或以某种方式处理正在客户端和服务端之间交换的数据流
Filter的使用:
与使用servlet类似,Filter是java web提供的一个接口,开发者只需要定义一个类并实现该接口即可。
注:
- 如果 有多个Filter,它的执行顺序与web.xml文件中的配置顺序决定的
- 可以通过注解的方式简化web.xml中的配置
实际开发的使用场景:
- 同一处理中文乱码
- 屏蔽敏感词
- 控制资源访问权限
Filter的生命周期
当Tomcat启动时, 通过反射机制调用Filter的无参构造函数创建实例化对象,同时调用init方法初始化,doFilter方法调用多次,当Tomcat服务器关闭的时候,调用destroy来销毁Filter对象。
无参构造函数:只调用一次,当Tomcat启动时调用(Filter一定要进行配置)
init方法:只调用一次,当Filter的实例化对象创建完成之后调用
doFilter:调用多次,访问Filter的业务逻辑
destroy:只调用一次 ,Tomcat关闭时调用
文件上传下载
文件上传(客户端传到服务端)
- 在JSP文件中
- input的type设置为file
- form表单的method设置post,get请求会将文件名传给服务器,而不是文件本身
- form表单的enctype属性设置multipart/form-data,以二进制的形式传输数据
- Servlet
//通过输入流获取客户端传来的数据
InputStream inputStream = req.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);//输入字节流转输入字符流
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);//输入字符流
//通过输出流将数据输出到硬盘
String realPath = req.getServletContext().getRealPath("file/copy.txt");//获取file的绝对路径
OutputStream outputStream = new FileOutputStream(realPath);
Writer writer = new OutputStreamWriter(outputStream);
BufferedWriter bufferedWriter = new BufferedWriter(writer);
String str="";
while((str=bufferedReader.readLine())!=null){
System.out.println(str);
bufferedWriter.write(str);//边读边写入
}
bufferedWriter.close();
writer.close();
outputStream.close();
bufferedReader.close();
inputStreamReader.close();
inputStream.close();
fileupload组件可以将所有请求信息都解析成FileItem对象,可以通过对FileItem对象的操作完成上传。
下载jar包
Commons IO – Download Apache Commons IO
//获取FileItem对象
try {
DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
List<FileItem> list = servletFileUpload.parseRequest(req);
System.out.println(list);
//list中可能包含前台输入文本或者文件
for (FileItem item: list) {
if(item.isFormField()){//如果此是一个框
String name = item.getFieldName();
String value = item.getString("UTF-8");
System.out.println(name+":"+value);
}else {//表示是一个文件,选哟上传文件
String filename = item.getName();
long size = item.getSize();
System.out.println(filename+":"+size);
InputStream inputStream = item.getInputStream();//读取输入流
String realPath = req.getServletContext().getRealPath("file/"+filename);//获取file的绝对路径
FileOutputStream fileOutputStream = new FileOutputStream(realPath);
int temp = 0;
while((temp = inputStream.read()) != -1){
fileOutputStream.write(temp);
}
fileOutputStream.close();
inputStream.close();
System.out.println("上传成功");
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
文件下载(客户端从服务端下载文件)
inputstream输入流将服务器本地的文件读到Java内存中
再用outstream输出流输出到客户端的浏览器中(浏览器自带下载工具)
@WebServlet("/download")
public class DownloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置响应方式
resp.setContentType("application/x-msdownload");
//设置下载之后需要一个文件名
String fileName = "test.txt";
resp.setHeader("Content-Disposition", "attachment;filename=" + fileName);
//获取输出流
ServletOutputStream outputStream = resp.getOutputStream();
//
String realPath = req.getServletContext().getRealPath("file/test.txt");
FileInputStream fileInputStream = new FileInputStream(realPath);
int temp = 0;
while ((temp = fileInputStream.read()) != -1) {
outputStream.write(temp);
}
fileInputStream.close();
outputStream.close();
}
}
Ajax
(Asynchronous JavaScript And XML 异步的JavaScrip和XML )
ajax指的是一种交互方式,异步加载,客户端和服务器的数据交互更新在局部页面技术,不需要刷新整个页面(局部刷新)
基于jQuery的AJAX
注意:不能再用表单提交请求,改用jQuery方式绑定事件来提交
servlet不能跳转jsp,只能将数据返回
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
<script src="https://code.jquery.com/jquery-1.12.4.js" integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU=" crossorigin="anonymous"></script>
</head>
<body>
<%--<form action="/test" method="post">--%>
<input id="text" type="text" name="name"><br>
<input id="btn" type="button" value="提交">
<%--</form>--%>
</body>
<script type="text/javascript">
$(function (){
var btn = $("#btn");//获取结点 #是id的选择器
btn.click(function (){//btn对象绑定点击事件
$.ajax({
url:'/test',//相当于from里面的action对应的内容
type:'post',//相当于from里面的method
data:'id=1',//想要传的参数,例如网页地址栏的参数 也可以写成url:'/test?id=1'
dataType:'text',//服务端返回的数据类型 文本text 对象JSON
success:function (data){//上面请求成功 data服务器响应的内容
var text =$("#text");
text.before("<span>"+data+"<span><br/>");
}
});
});
})
</script>
</html>
@WebServlet("/test")
public class TestServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String id = req.getParameter("id");
try {
Thread.sleep(3000);//延时
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
String str = "Hello World";
resp.getWriter().write(str);
// req.setAttribute("str",str);
// req.getRequestDispatcher("test.jsp").forward(req,resp);
}
}
JDBC
JDBC的使用
一般不使用Statement,使用PreparedStatement;是Statement的子类,提供SQL占位符的功能。
使用Statement进行开发有两个问题:
1、需要频繁拼接String字符串,出错率较高。
2、存在SQL注入的风险
Statement的方式
PreparedStatement的方式