在Java中,动态Web资源开发的技术统称为JavaWeb
Web应用程序
可以提供浏览器访问的程序
web应用程序编写完后,若想提供给外界访问,需要一个服务器来同意管理
静态web
动态web
页面会动态展示,web页面展示效果因人而异
缺点:加入服务器的动态web资源出现了错误,需要重新编写后台的程序
优点:可以动态更新,与数据库交互
ASP
php
JSP/Servlet
服务器是一种被动的操作,用来处理用户的一下请求和给用户的一下响应信息
IIS
Tomcat
下载Tomcat
可能遇到的问题:
? - Java环境变量没有配置
? -闪退问题:需要配置兼容性
? -乱码问题:在配置文件中设置
高频面试题:网站如何进行访问的
->输入一个域名,回车
->检查本机的C:\Window\System32\drivers\etc\hosts配置文件下有没有这个域名映射
->有:直接返回对应的ip地址,这个地址中,有我们需要访问的web程序,可以直接访问
->没有,去DNS服务器上查询,找的话就返回,找不到就返回
网站的结构
--webapps:Tomcat服务器的web目录
-ROOT
-ming:网站的目录名
-web-inf
-classes java程序
-lib web应用依赖包
-web.xml 网站配置文件
-index.html
HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,HTTP是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII码形式给出;而消息内容则具有一个类似MIME的格式
Https:安全的
http1.0
http2.0
客户端->发请求->服务器
Request URL: https://www.baidu.com/ 请求地址
Request Method: GET 请求方法
Status Code: 200 OK 状态码
Remote Address: 36.152.44.96: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
Cookie: PSTM=1572915522; BAIDUID=AEE83A4561351C047835C81814E7DAB3:FG=1; BDORZ=B490B5EBF6F3CD402E515D22BCDA1598; __cfduid=dd901a57541008dfd0526053e84d327641601701966; COOKIE_SESSION=43143_2_7_1_27_15_0_0_5_5_1_0_43105_0_2_0_1601783578_1600787276_1601783576%7C9%23914695_54_1601701964%7C9; __yjsv5_shitong=1.0_7_029c42c2330bce56039f567defeeb8eab188_300_1601783791000_223.104.6.2_91d6f323; BD_HOME=1; delPer=0; BD_CK_SAM=1; PSINO=3; H_PS_645EC=0adb8OnixJEvwehHv06qoTetzPAQswro0E1MQyD1BqaqwQq19lHx2X4yECM; BIDUPSID=0ECED95EB3E98304F84B985062804BB4; BD_UPN=19314753; H_PS_PSSID=32756_32617_1468_32734_31660_32723_32230_7517_32719
Host: www.baidu.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.81 Safari/537.36 SE 2.X MetaSr 1.0
请求行
消息头:
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式, GBK,UTF-8 GB2312
Accept-Language:告诉浏览器它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成时断开还是保持连接
Host:
服务端->响应->客户端
Cache-Control: private 缓存控制
Connection: keep-alive 连接:
Content-Encoding: gzip 编码
Content-Type: text/html;charset=utf-8 类型
响应体:
Accept:告诉浏览器,它所支持的数据类型
Accept-Encoding:支持哪种编码格式, GBK,UTF-8 GB2312
Accept-Language:告诉浏览器它的语言环境
Cache-Control:缓存控制
Connection:告诉浏览器,请求完成时断开还是保持连接
Host:
Refresh:告诉客户端,多久刷新一遍
Location:让网页重新定位
响应状态码
Maven的核心思想:约定大于配置
下载
配置环境变量
阿里云镜像
镜像:mirrors
国内建议阿里云镜像
<mirror>
<id>alimaven</id>
<mirrorOf>central</mirrorOf>
<name>aliyun maven</name>
<!-- 国内推荐阿里云的Maven镜像 -->
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
</mirror>
<localRepository>D:\maven-3.6.3\my_repository</localRepository>
不用模板的maven项目
可以为标记功能目录,或者在Project Structure中标记
在idea中配置Tomcat
pom.xml文件是核心文件
package:项目打包方式
jar:java应用
war:web应用
maven资源导出失败,解决办法
<build>
<resources>
<resource>
<directory>src/main/resource(资源目录)</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
maven默认的web项目中web.xml版本是2.3,选择Tomcat里的最新的5.0,不会出现版本问题
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
metadata-complete="true">
</web-app>
java,resources,标记为功能目录
web.xml注册
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
https://jakarta.ee/xml/ns/jakartaee/web-app_5_0.xsd"
version="5.0"
metadata-complete="true">
<!--注册servlet-->
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.company.servlet.HelloServlet</servlet-class>
</servlet>
<!--一个servlet对应一个Mapping映射-->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!--请求路径-->
<url-pattern>/ming</url-pattern>
</servlet-mapping>
</web-app>
helloServlet编写
package com.company.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hello World!</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World!</h1>");
out.println("</body>");
out.println("</html>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
Servlet就是sun公司开发动态web的一门技术
sun在这些API中提供一个接口叫做:Servlet
如果你想开发一个Servlet程序,只需要完成两个小步骤
把实现了Servlet接口的程序叫做,Servlet
Servlet接口有两个默认的实现类:HttpServlet,GenericServlet
构建一个普通的maven项目,删掉里面的src目录,以后就在这个项目里建立Module,这个空的工程就是maven主工程
关于maven父子工程的理解
父项目中会有
<modules>
<module>servlet-01</module>
</modules>
子项目中
<parent>
<artifactId>Mavendemo</artifactId>
<groupId>org.company</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目中的jar包子项目中可以直接使用
Maven环境优化
编写一个Servlet程序
package com.company;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class HelloServlet extends HttpServlet {
//由于get后者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();//响应流
writer.print("Hello,Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
编写Servlet的映射web.xml
为什么需要映射:我们写的是Java程序,但是要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册写的servlet,还需给他一个浏览器能访问的路径
<!--注册servlet-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>com.company.HelloServlet</servlet-class>
</servlet>
<!--一个servlet对应一个Mapping映射-->
<servlet-mapping>
<servlet-name>hello</servlet-name>
<!--请求路径-->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
Servlet是由web服务器调用,web服务器在收到浏览器请求后,调用相应的Servlet
优先级问题:指定了固有的映射路径优先级最高,找不到就会走默认的请求
响应乱码问题可以修改
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
web容器在启动的时候,它会为每个Web程序都创建一个对应的ServletContext对象,它代表了当前的web应用
共享数据
我在这个Servlet中保存的数据,可以在另外一个Servlet中拿到
获取初始化参数
//web.xml
<contextparam>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</contextparam>
ServletContext servletContext = this.getServletContext();
String url = servletContext.getInitParameter("url");
ServletContext servletContext = this.getServletContext();
servletContext.getRequestDispatcher("/ser1").forward(req,resp);//调用forward方法实现转发
发现都被打包到了同一个路径下,classes,我们俗称这个路径为classpath
思路:需要一个文件流
//db.properties
username=root
password=123456
ServletContext servletContext = this.getServletContext();
InputStream is = servletContext.getResourceAsStream("/WEB-INF/classes/dp.properties");
Properties pro = new Properties();
pro.load(is);
String username = pro.getProperty("username");
String password = pro.getProperty("password");
resp.getWriter().print(username+":"+password);
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的HttpServletResponse对象
负责向浏览器发送数据的方法
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 var1, 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 var1, int var2);
void setStatus(int var1);
String path = this.getServletContext().getRealPath("1.png");
String filename = path.substring(path.lastIndexOf("//")+1); //URLEncode解决乱码问题
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(path,"utf-8"));
FileInputStream in = new FileInputStream(path);
int len = 0;
byte[] buffer = new byte[1024];
ServletOutputStream out = resp.getOutputStream();
while((len=in.read())!=-1){
out.write(buffer,0,len);
}
in.close();
out.close();
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器5秒自动刷新一次
resp.setHeader("refresh","5");
//在内存中创建图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D graphics = (Graphics2D) image.getGraphics();//笔
//设置图片的背景颜色
graphics.setColor(Color.white);
graphics.fillRect(0,0,80,20);
//给图片写数据
graphics.setColor(Color.blue);
graphics.setFont(new Font(null,Font.BOLD,20));
graphics.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;
}
实现重定向
/*resp.setHeader("Location","/img");
resp.setStatus(302);*/
resp.sendRedirect("/img");
重定向和转发的区别
页面都会转发
请求转发的时候,url不会发生变化
重定向的时候,url会发生变化
重定向的时候注意路径,要加上项目的路径
index.jsp
<%--${pageContext.request.contextPath}代表当前的项目--%>
<form action="${pageContext.request.contextPath}/hello" method="get">
用户名:<input type="text" name="username">
密码:<input type="password" name="password">
<input type="submit">
</form>
String username = req.getParameter("username");
String password = req.getParameter("password");
常见场景:
? 登录界面
原文:https://www.cnblogs.com/uxquan/p/13768922.html