web开发:
可以提供浏览器访问的程序;
Web酸用程序编写完毕后,若想提供给外界访问;需费一个服务器来统一管理
*.htm, *.html这些都是网页的后缀、如果服务器上一直存在这些东四,我们就可以直接进行读取、需要网络;
静态web存在的缺点
页面会动态展示,“web页面的展示效果因人而异”
缺点:
优点:
ASP:
php:
jSP/Servlet:
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息;
lIS:微软的;
ASP.,Windows中自带的
Tomcat
面向百度编程:
Tomcat是Apache 软件基金会(Apache Software Foundation)的jakarta项目中的一个核心项目,最新的Servlet 和ISP 规范总是能在Tomcat中得到体现,因为Tomcat 技术先进、性能稳定,而且免费,因而深受lava爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试ISP程序的首选。对于一个Java初学web的人来说,它是最佳的选择
Tomcat 实际上运行JSP页面和Serlet。Tornct最新版易9.0
工作3-5年之后,可以尝试手写Tomcat服务器;
下载tomcat:
官网:http://tomcat.apache.org/
文件夹作用:
访问测试:http://localhost:8080/
可能遇到的问题:
可以修改 conf/logging.properties 中的 java.util.logging.ConsoleHandler.encoding = GBK 解决乱码问题
可以配置启动的端口号
<Connector port="8081" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
可以配置主机的名称
<Host name="www.qinjiang.com" appBase="webapps" unpackWARs="true" autoDeploy="true">
高难度面试题:
请你谈谈网站是如何进行访问的!
127.0.0.1 www.qinjiang.com
4.可以配置一下环境变量(可选性)
不会就先模仿
将自己写的网站,放到服务器(Tomcat)中指定的web应用的文件夹(webapps)下,就可以访问了
网站应该有的结构
--webapps :Tomcat服务器的web目录 -ROOT -kuangstudy :网站的目录名 - WEB-INF -classes : java程序 -lib:web应用所依赖的jar包 -web.xml :网站配置文件 - index.html 默认的首页 - static -css -style.css -js -img -.....
HTTP协议:面试
Maven:构建工具
Maven安装包
Servlet入门
HelloWorld!
Servlet配置 ·原理
http:
(超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上。
Https:安全的
http1.0
HTTP/1.0:客户端可以与web服务器连接后,只能获得一个web资源,断开连接
http2.0
HTTP/1.1:客户端可以与web服务器连接后,可以获得多个web资源。
客户端–发请求(Request)–服务器
百度:
Request URL:https://www.baidu.com/ 请求地址 Request Method:GET get方法/post方法 Status Code:200 OK 状态码:200 Remote(远程) Address:14.215.177.39:443 Accept:text/html Accept-Encoding:gzip, deflate, br Accept-Language:zh-CN,zh;q=0.9 语言 Cache-Control:max-age=0 Connection:keep-alive
1、请求行
请求行中的请求方式:GET
请求方式:Get,Post,HEAD,DELETE,PUT,TRACT.…
get:请求能够携带的参数比较少,大小有限制,会在浏览器的URL地址栏显示数据内容,不安全,但高效
post:请求能够携带的参数没有限制,大小没有限制,不会在浏览器的URL地址栏显示数据内容,安全,但不高效。
2、消息头
Accept:告诉浏览器,它所支持的数据类型 Accept-Encoding:支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1 Accept-Language:告诉浏览器,它的语言环境 Cache-Control:缓存控制 Connection:告诉浏览器,请求完成是断开还是保持连接 HOST:主机..../.
4.4、Http响应
服务器–响应…….客户端
百度:
Cache-Control:private 缓存控制 Connection:Keep-Alive 连接 Content-Encoding:gzip 编码 Content-Type:text/html 类型
1、响应体
Accept:告诉浏览器,它所支持的数据类型 Accept-Encoding:支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1 Accept-Language:告诉浏览器,它的语言环境 Cache-Control:缓存控制 Connection:告诉浏览器,请求完成是断开还是保持连接 HOST:主机..../. Refresh:告诉客户端,多久刷新一次; Location:让网页重新定位;
2、响应状态码
200:请求响应成功200
3xx:请求重定向·重定向:你重新到我给你新位置去;
4xx:找不到资源404·资源不存在;
5xx:服务器代码错误 500 502:网关错误
常见面试题:
当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?
我为什么要学习这个技术?
在Javaweb开发中,需要使用大量的jar包,我们手动去导入;
如何能够让一个东西自动帮我导入和配置这个jar包。
由此,Maven诞生了!
我们目前用来就是方便导入jar包的!
Maven的核心思想:约定大于配置
有约束,不要去违反。
Maven会规定好你该如何去编写我们Java代码,必须要按照这个规范来;
官网:https://maven.apache.org/
下载完成后,解压即可;
小狂神友情建议:电脑上的所有环境都放在一个文件夹下,方便管理;
在我们的系统环境变量中配置如下配置:
M2_HOME maven目录下的bin目录
MAVEN_HOME maven的目录
在系统的path中配置%MAVEN_HOME%\bin
测试Maven是否安装成功,保证必须配置完毕!
镜像:mirrors
作用:加速我们的下载
国内建议使用阿里云的镜像
<mirror>
<id>nexus-aliyun</id>
<mirrorOf>*,!jeecg,!jeecg-snapshots</mirrorOf>
<name>Nexus aliyun</name>
<url>http://maven.aliyun.com/nexus/content/groups/public</url>
</mirror>
D:Enmvironment\apache-maven-3.6.2conf\ettings.xml
(狂神老师配置源和仓库的文件位置)
在本地的仓库,远程仓库; 建立一个本地仓库:localRepository
<localRepository>D:\Environment\apache-maven-3.6.2\maven-repo</localRepository>
1
5.6 ~ 5.13笔记-下载地址
(拒接度盘)下载地址:https://lanzoui.com/ibuibxi
后面的 5.6 ~ 5.13 + 案例演示 (图)
后面第 5 剩下部分的笔记建议配合狂神的
“javaweb-06:IDEA中Maven的操作”、“javaweb-07:解决大家遇到的一些问题”
仔细(回)看
Servlet就是sun公司开发动态web的一门技术
Sun在这些APi中提供一个接口叫做:Servlet,如果你想开发一个Servlet程序,只需要完成两个小步骤:
编写一个类,实现Serlet接口
把开发好java类部署到web服务器中。
把实现了Servlet接口的Java程序叫做,Servlet
Serlvet接口Sun公司有两个默认的实现类:HttpServlet,GenericServled
6.2、HelloServlet
构建一个普通的Maven项目,等理面的sc目录,以后我们的学习就在这个项目里面建立Moudel;这个空的工程就题Maven主工程;
关于Maven父子工程的理解;
父项目中会有
<modules>
<module>servlet-01</module>
</modules>
子项目会有
<parent>
<artifactId>javaweb-02-servlet</artifactId>
<groupId>com.kuang</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目中的java子项目可以直接使用
son extends father
1
Maven环境优化
修改web.xml为最新的
将maven的结构搭建完整
.
编写一个Servlet程序
编写一个普通类
实现Servlet接口,这里我们直接继承HttpServlet
public class HelloServlet extends HttpServlet {
//由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter(); //响应流
writer.print("Hello,Serlvet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
编写Servlet的映射
为什么需要映射:我们写的是JAVA程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需
要再web服务中注册我们写的Servlet,还需给他一个浏览器能够访问的路径;
<!--注册Servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.kuang.servlet.HelloServlet</servlet-class>
</servlet>
<!--Servlet的请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
配置Tomcat
注意:配置项目发布的路径就可以了
启动测试,OK!
6.3、Servlet原理
Servlet是由Web服务器调用,web服务器在收到浏览器请求之后,会:
6.4、Mapping问题
一个Servlet可以指定一个映射路径
.
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
一个servlet可以指定多个映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello3</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello4</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello5</url-pattern>
</servlet-mapping>
一个servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/hello/*</url-pattern>
</servlet-mapping>
默认请求路径
<!--默认请求路径-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
指定一些后缀或者前缀等等…
<!--可以自定义后缀实现请求映射
注意点,*前面不能加项目映射的路径
hello/sajdlkajda.qinjiang
-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.qinjiang</url-pattern>
</servlet-mapping>
优先级问题
指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;
<!--404-->
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>com.kuang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;
1、共享数据
我在这个Servlet中保存的数据,可以在另外一个servlet中拿到;
public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //this.getInitParameter() 初始化参数 //this.getServletConfig() Servlet配置 //this.getServletContext() Servlet上下文 ServletContext context = this.getServletContext(); String username = "秦疆"; //数据 context.setAttribute("username",username); //将一个数据保存在了ServletContext中,名字为:username 。值 username } }
public class GetServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String username = (String) context.getAttribute("username"); resp.setContentType("text/html"); resp.setCharacterEncoding("utf-8"); resp.getWriter().print("名字"+username); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
<servlet> <servlet-name>hello</servlet-name> <servlet-class>com.kuang.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> <servlet> <servlet-name>getc</servlet-name> <servlet-class>com.kuang.servlet.GetServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>getc</servlet-name> <url-pattern>/getc</url-pattern> </servlet-mapping>
测试访问结果;
2、获取初始化参数
<!--配置一些web应用初始化参数--> <context-param> <param-name>url</param-name> <param-value>jdbc:mysql://localhost:3306/mybatis</param-value> </context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); String url = context.getInitParameter("url"); resp.getWriter().print(url); }
3、请求转发
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext context = this.getServletContext(); System.out.println("进入了ServletDemo04"); //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径 //requestDispatcher.forward(req,resp); //调用forward实现请求转发; context.getRequestDispatcher("/gp").forward(req,resp); }
4、读取资源文件
Properties
在java目录下新建properties
在resources目录下新建properties
发现:都被打包到了同一个路径下:classes,我们俗称这个路径为classpath:
思路:需要一个文件流
username=root12312
password=zxczxczxc
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/kuang/servlet/aa.properties");
Properties prop = new Properties();
prop.load(is);
String user = prop.getProperty("username");
String pwd = prop.getProperty("password");
resp.getWriter().print(user+":"+pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
访问测试即可ok;
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest
对象,代表响应的一个HttpServletResponse;
1
2
如果要获取客户端请求过来的参数:找HttpServletRequest
如果要给客户端响应一些信息:找HttpServletResponse
1、简单分类
负责向浏览器发送数据的方法
servletOutputstream getOutputstream() throws IOException;
Printwriter getwriter() throws IOException;
负责向浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String varl,long var2)
void addDateHeader(String var1,long var2)
void setHeader(String var1,String var2);
void addHeader(String var1,String var2);
void setIntHeader(String var1,int var2);
void addIntHeader(String varl,int var2);
响应的状态码2、下载文件
向浏览器输出消息(一直在讲,就不说了)
下载文件
要获取下载文件的路径
下载的文件名是啥?
设置想办法让浏览器能够支持下载我们需要的东西
获取下载文件的输入流
创建缓冲区
获取OutputStream对象
将FileOutputStream流写入到bufer缓冲区
使用OutputStream将缓冲区中的数据输出到客户端!
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 1. 要获取下载文件的路径 String realPath = "F:\\班级管理\\西开【19525】\\2、代码\\JavaWeb\\javaweb-02-servlet\\response\\target\\classes\\秦疆.png"; System.out.println("下载文件的路径:"+realPath); // 2. 下载的文件名是啥? String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1); // 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码 resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8")); // 4. 获取下载文件的输入流 FileInputStream in = new FileInputStream(realPath); // 5. 创建缓冲区 int len = 0; byte[] buffer = new byte[1024]; // 6. 获取OutputStream对象 ServletOutputStream out = resp.getOutputStream(); // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端! while ((len=in.read(buffer))>0){ out.write(buffer,0,len); } in.close(); out.close(); }
3、验证码功能
验证怎么来的?前端实现
后端实现,需要用到Java的图片类,生产一个图片
package com.kuang.servlet; import javax.imageio.ImageIO; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; public class ImageServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //如何让浏览器3秒自动刷新一次; resp.setHeader("refresh","3"); //在内存中创建一个图片 BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB); //得到图片 Graphics2D g = (Graphics2D) image.getGraphics(); //笔 //设置图片的背景颜色 g.setColor(Color.white); g.fillRect(0,0,80,20); //给图片写数据 g.setColor(Color.BLUE); g.setFont(new Font(null,Font.BOLD,20)); g.drawString(makeNum(),0,20); //告诉浏览器,这个请求用图片的方式打开 resp.setContentType("image/jpeg"); //网站存在缓存,不让浏览器缓存 resp.setDateHeader("expires",-1); resp.setHeader("Cache-Control","no-cache"); resp.setHeader("Pragma","no-cache"); //把图片写给浏览器 ImageIO.write(image,"jpg", resp.getOutputStream()); } //生成随机数 private String makeNum(){ Random random = new Random(); String num = random.nextInt(9999999) + ""; StringBuffer sb = new StringBuffer(); for (int i = 0; i < 7-num.length() ; i++) { sb.append("0"); } num = sb.toString() + num; return num; } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } } <servlet> <servlet-name>ImageServlet</servlet-name> <servlet-class>com.kuang.servlet.ImageServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Imageservlet</servlet-name> <url-pattern>/img</url-pattern> </servlet-mapping>
常见场景:
用户登录
void sendRedirect(String var1) throws IOException;
1
测试:
@override protected void doGet(HttpservletRequest req, HttpservletResponse resp) throws ServletException, IOException { resp. sendRedirect("/r/img");//重定向 /* resp. setHeader("Location","/r/img"); resp. setstatus (302); * }
index.jsp
<html> <body> <h2>Hel1o World!</h2> 《%--这里超交的路径,需要寻找到项目的路径--%> <%--${pageContext. request, contextPath}代表当前的项目--%> <form action="${pageContext. request.contextPath}/login" method="get"> 用户名: <input type="text" name="username"> <br> 密码: <input type="password" name="password"> <br> <input type="submit"> </form> </body> </html>
会话:用户打开浏览器,点击很多超链接,访问多个web资源,最后关闭浏览器,该过程称为会话
有状态会话:一个同学来过教室,下次再来,就会知道这个同学·来过教室
一个网站,怎么证明你来过?
服务端 客户端
1,服务端给客户一个信件,客户下次访问带上该信件即可cookie
2,服务端登记客户来过,下次来匹配你 session
cookie
session
常见:第一次登陆,第二次在登录时直接进入了
public class CookieDemo01 extends HttpServlet { //保存用户上一次访问的时间 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //服务器告诉你 你来的时间并封装一个信封,下次来带这个信封就知道你来了 //解决中文乱码 req.setCharacterEncoding("utf-8"); resp.setCharacterEncoding("utf-8"); //让客户端返回字符串,需要一个输出对象 PrintWriter out = resp.getWriter(); //Cookie服务器端从客户端取得,客户端对应请求request Cookie[] cookies = req.getCookies(); //判断cookie是否存在 if (cookies != null) { //如果存在怎么办 out.write("您上次访问时间是:"); for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; //获取cookie名字 if (cookie.getName().equals("LastLoginTime")) { //获取cookie值 long LastLoginTime = Long.parseLong(cookie.getValue());//如何把该字符串输出,先解析成长整形,把字符串变成一个时间戳 Date date = new Date(LastLoginTime); out.write(date.toLocaleString()); } } } else { out.write("这是您第一次访问本站"); } //服务器给客户端响应cookie resp.addCookie(new Cookie("LastLoginTime", System.currentTimeMillis() + ""));//加上" ",使时间变成字符串输出 } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }