文本:html,字符串,~..
超文本:图片,音乐,视屏,定位,地图...
端口为80
Https:安全的,端口号443
http1.0
http2.0
Request URL: https://www.baidu.com/ 请求地址
Request Method: GET get方法/post方法
Status Code: 200 OK 状态码:200
Remote(远程地址) Address: 39.156.66.14:443
Accept: text/html
Accept-Language: zh-CN,zh;q=0.9
Cache-Control: max-age=0
Connection: keep-alive
请求行中的请求方式:get
请求方式:Get,Post
Accept: 告诉浏览器,他所支持的数据类型
Accept-Language: zh-CN,zh;q=0.9,告诉浏览器,它的语言环境
Cache-Control: max-age=0: 缓存控制
Connection: keep-alive:告诉浏览器,请求完成是断开还是保持连接
HOST:主机
百度:
Cache-Control: private
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html;charset=utf-8
Accept: 告诉浏览器,他所支持的数据类型
Accept-Language: zh-CN,zh;q=0.9,告诉浏览器,它的语言环境
Cache-Control: max-age=0: 缓存控制
Connection: keep-alive:告诉浏览器,请求完成是断开还是保持连接
HOST:主机
Refresh:告诉客户端,多久刷新一次;
Location:让网页重新定位
3xx:请求重定向
4xx:找不到资源
5xx:服务器代码错误 500 ,502:网关错误
常见面试题:
当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么?
在Javaweb开发中,需要使用大量的jar包,我们手动去导入
如何能够让一个东西自动帮我导入和配置这个jar包,由此,Maven诞生了
https://maven.apache.org/download.cgi

vim ~/.bash_profile
然后将以下配置加入里面
MAVEN_HOME=/Users/twq/Downloads/apache-maven-3.8.6
PATH=$MAVEN_HOME/bin:$PATH
M2_HOME=/Users/twq/Downloads/apache-maven-3.8.6/bin
export MAVEN_HOME
export PATH
export M2_HOME
最后输入 mvn -v
出现如下图表名配置成功

Windows:
在环境变量中添加M2_home和MAVEN_HOME两个路径

并继续添加PATH的路径

镜像: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>
将此配置放入setting.xml的mirrors中即可

<localRepository>/Users/twq/Downloads/apache-maven-3.8.6/maven-repo</localRepository





进来后可能还会显示pom.xml(Unknown)
我的第一次进来是这样,不知道为啥我的pom.xml里是空白的
最后自己手动添加了如下
<?xml version="1.0" encoding="UTF-8" ?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example </groupId>
<!--项目名-->
<artifactId>tang</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
进入后如果没有自动下载maven依赖,则可以自己在IDEA的终端输入以下命令下载
mvn dependency:resolve-plugins
最后出现如下图所示则表明下载成功

成功后,自己建的maven仓库里就有了很多文件


这里会自动显示你想要的src以及test文件

创建完成如下图所示








方法二:


启动Tomcat会直接显示webapp里面的index.jsp文件里的内容



<?xml version="1.0" encoding="UTF-8" ?>
<!--maven的版本和头文件-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example </groupId>
<artifactId>tang</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- Package:项目打包的方式
jar:Java应用
war:javaweb应用
-->
<!-- <packaging>war</packaging>-->
<!-- <!– 配置 –>-->
<!-- <properties>-->
<!-- <!–项目默认构建编码–>-->
<!-- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>-->
<!-- <!–编译版本–>-->
<!-- <maven.compiler.source>1.8</maven.compiler.source>-->
<!-- <maven.compiler.target>1.8</maven.compiler.target>-->
<!-- </properties>-->
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.22</version>
</dependency>
</dependencies>
<!-- 在build中配置resource,防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>

Servlet就是sun公司开发动态web的一门技术
Sun在这些API中提供一个接口叫做:Servelt,如果你想开发一个Servlet程序,只需要完成两个小步骤:
把实现了Servlet接口的Java程序叫做Servlet
<!--指明该父类下的子模块-->
<modules>
<module>Servlet-01</module>
</modules>
子项目中会有
<!-- 子类必须指明父类-->
<parent>
<artifactId>javaweb-02-Servlet</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
父项目中的Java,子项目可以直接使用
注意:
父项目的打包方式必须为pom且必须要定义打包方式,子项目的打包方式必须为jar,否则会报错:Invalid packaging for parent POM org.example:javaweb-02-Servlet:1.0-SNAPSHOT (/Users/twq/Downloads/javaweb-02-Servlet/pom.xml), must be "pom" but is "jar"
Tomcat中Servlet的使用样例链接
http://localhost:8080/examples/servlets/


上图若没有搜索到,则可去Maven仓库中寻找

一搜发现搜到一堆没用的,心想既然在Tomcat上能使用肯定是导入了某一个与HttpServlet相关的jar包,于是乎又来到Tomcat的lib目录(存放各种jar包的地方)下查找

发现lib目录下与servlet相关的jar包只有一个,于是再次回到maven仓库中寻找该jar包



我选择的是导入maven依赖,复制上图方框里的依赖代码,依赖里的



然后将Tomcat中Servlet下的hello样例代码粘贴过来,就是如下代码
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>");


<!--注册servlet-->
<servlet>
<!--随便起个名字-->
<servlet-name>hello</servlet-name>
<servlet-class>com.tang.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<!--请求路径 -->
<url-pattern>/Twq</url-pattern>
</servlet-mapping>
可以根据输入的指定路径如我的指定的Twq路径http://localhost:8080/Servlet_01_war/Twq,然后根据Twq请求路径在Servlet-mapping中找到servlet-name也即是hello,然后在根据注册的servlet-name找到要执行的Java程序,最后运行Java程序
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!--请求路径 -->
<url-pattern>/Twq/*</url-pattern>
</servlet-mapping>
测试数据:
http://localhost:8080/Servlet_01_war/Twq/fafsdafgsfvdsfsdgg
测试结果:

<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!--请求路径 -->
<!--注意点 .*前面不能加项目映射的路径否则会启动Tomcat报错 -->
<url-pattern>*.Twq</url-pattern>
</servlet-mapping>
测试数据:
http://localhost:8080/Servlet_01_war/sdfadfvfsgsddfrqw.Twq
测试结果:
发现只要后缀是.Twq结尾前面是什么无所谓

web.xml代码
<?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">
<!-- web.xml中是配置我们web的核心应用-->
<!--注册servlet-->
<servlet>
<!--随便起个名字-->
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.tang.HelloServlet</servlet-class>
</servlet>
<!--一个servlet对应一个mapping:映射-->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<!--请求路径 -->
<url-pattern>/Twq</url-pattern>
</servlet-mapping>
</web-app>



完成上面几步之后可以解决此问题,Tomcat就可以正常启动了
运行结果图



解决方法:
设置浏览器的响应的编码格式即可


HelloServlet代码
package com.tang;
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 {
//响应的类型:html
response.setContentType("text/html");
//设置浏览器响应的编码格式
response.setCharacterEncoding("UTF-8");
//获取响应的输出流
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>唐昊!!</h1>");
out.println("</body>");
out.println("</html>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
在这个Servlet中保存的数据,可以咋另外一个Servlet中拿到;
存放数据的类
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//响应的类型:html
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.setHeader("text/html","UTF-8");
resp.getWriter().println("姓名:"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml
<?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-name>hello</servlet-name>
<servlet-class>com.tang.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/Twq1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>get</servlet-name>
<servlet-class>com.tang.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>get</servlet-name>
<url-pattern>/Twq2</url-pattern>
</servlet-mapping>
</web-app>
测试访问结果:


<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306</param-value>
</context-param>
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>com.tang.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
ServletDemo03中代码如下
package com.tang;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.setContentType("text/html");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().println(url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
ServletDemo04代码
package com.tang;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletDemo04 extends HttpServlet {
@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实现请求转发
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web.xml 代码
<servlet>
<servlet-name>sd4</servlet-name>
<servlet-class>com.tang.ServletDemo04</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd4</servlet-name>
<url-pattern>/sd4</url-pattern>
</servlet-mapping>
运行结果图

转发的大致思想:
比如有A,B,C,现在有一个需求是A想要拿到C的资源,但是A又无法直接调用C,且只能连接到B,就只能B找C拿,然后C在返回给B,最后B在将C返回的数据交给A,这个过程中,A和C始终没有见到C,所以上图路径没有变化(用sd4的路径去访问jp路径里面的内容),图形化过程如下:

在Java目录下新建Properties
在resource目录下新建Properties
发现:都被打包到了同一个路径下:classes,我么俗称这个路径为classpath:
当在java目录下写资源文件时,并不会被打包,可以通过如下方法解决,将以下代码放入当前模块的pom.xml中即可
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>

加上之后再重新打包,就会生成资源文件

开始读取该资源文件的流
aa.properties文件里的内容如下:
username=root
password=123456
web.xml代码
<servlet>
<servlet-name>sd5</servlet-name>
<servlet-class>com.tang.ServletDemo05</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sd5</servlet-name>
<url-pattern>/sd5</url-pattern>
</servlet-mapping>
ServletDemo05代码如下:
package com.tang;
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.InputStream;
import java.util.Properties;
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream resource = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/tang/aa.properties");
Properties properties = new Properties();
properties.load(resource);
String username = properties.getProperty("username");
String password = properties.getProperty("password");
resp.getWriter().println(username+":"+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
当前项目路径

运行结果图

如果要获取客户端请求过来的参数:找HttpSerletRequest
如果要给客户端响应一些信息:找HttpServletResponse
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
②负责向浏览器发送响应头的方法
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);
要获取下载文件的路径
下载的文件名是啥?
设置想办法让浏览器能够支持下载我们需要的东西
获取下载文件的输入流
输出获取到的输入流
<servlet>
<servlet-name>fileDown</servlet-name>
<servlet-class>com.tang.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>fileDown</servlet-name>
<url-pattern>/down</url-pattern>
</servlet-mapping>
该模块的pom.xml中尽量加上如下代码:
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<excludes>
<exclude>**/*.properties</exclude>
<exclude>**/*.xml</exclude>
</excludes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
FileServlet代码如下
package com.tang;
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.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp){
FileInputStream in = null;//将文件变成流
ServletOutputStream outputStream = null;
try {
//1.要获取下载文件的路径
String realPath = "/Users/twq/Downloads/javaweb-02-Servlet/out/artifacts/Servlet_03_war_exploded/WEB-INF/classes/唐三.jpg";
System.out.println("下载的文件的路径为:"+ realPath);
//2.下载的文件名是啥?
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);// 因为一个/需要转义,所以写两个表示截取到最后一个/,然后加1就表示最后一个/后面的名字,也即是文件名
//3.设置想办法让浏览器能够支持下载我们需要的东西
//Content-disposition:表示web下载文件的头消息,也是用其来支持下载我们需要的东西;中文文件名使用URLEncoder.encode编码,否则可能会乱码
resp.setHeader("Content-disposition","attachment;filename="+ URLEncoder.encode(fileName,"UtF-8"));
//4.获取下载文件的输入流
in = new FileInputStream(realPath);
//5.输出获取到的输入流
//6.创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
//7.获取OutputStream对象
outputStream = resp.getOutputStream();
//8.将FileOutputStream流写入到buffer缓冲区中,使用OutputStream将缓冲区中的数据输出到客户端
while((len=in.read(buffer)) != -1){
outputStream.write(buffer,0,len);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
//关闭流
if(in != null){
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(outputStream != null){
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
填写文件的绝对路径时,可以再out目录下去复制对应文件的绝对路径

运行结果图

前端实现
后端实现,需要用到Java的图片类,生成一个图片
web.xml注册代码
<servlet>
<servlet-name>ImageServlet</servlet-name>
<servlet-class>com.tang.ImageServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ImageServlet</servlet-name>
<url-pattern>/img</url-pattern>
</servlet-mapping>
ImageServlet代码
package com.tang;
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","2");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(100, 20, BufferedImage.TYPE_INT_RGB);
//得到图片,用一个2D的笔
Graphics2D g = (Graphics2D)image.getGraphics();
//设置图片的背景颜色
g.setColor(Color.white);
//fillRect:填充一个矩形,从(0,0)点开始到(80,20)结束填充一个背景为白色矩形
g.fillRect(0,0,100,20);
//给图片写数据
g.setColor(Color.red);//设置画笔颜色
g.setFont(new Font(null,Font.BOLD,20));//设置字体
g.drawString(makeNum(),0,20);//在(0,20)这个位置将随机数给画上去
//告诉浏览器,这个请求用图片的方式打开
resp.setContentType("image/jpg");
//网站存在缓存,设置不让浏览器缓存
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();
//7个9表示一个七位数,一个整数加上一个空串之后变为一个字符串
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>Redirect</servlet-name>
<servlet-class>com.tang.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Redirect</servlet-name>
<url-pattern>/red</url-pattern>
</servlet-mapping>
RedirectServlet代码
package com.tang;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
由运行结果下面结果图知下面这行代码等价于
resp.setHeader("Location","/Servlet_03_war/img");
resp.setStatus(302);
*/
resp.sendRedirect("/Servlet_03_war/img");//重定向
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
运行结果图

注意:重定向的路径要添加如下图所示的东西

不同点:
请求转发的时候,转发的url不会发生变化
重定向的时候,url地址栏会发生变化

RequestTest代码如下:
package com.tang;
import javax.naming.Context;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("有请求进来");
//处理请求
String username = req.getParameter("username");//获取请求参数的值
String password = req.getParameter("password");
System.out.println(username + ":" +password);
//重定向的时候一定添加web应用的路径,否则404
//resp.sendRedirect("/Servlet_03_war/Success.jsp");
/*转发的时候web应用的路径就不用写了,否则也会报404
因为这里的 / 代表的就是当前的web应用,在写就重复了*/
req.getRequestDispatcher("/Success.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml代码
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.tang.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
index.jsp代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--这里提交的路经,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}代表当前的项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="text" name="password"><br>
<input type="submit">
</form>
</body>
</html>
Success.jsp代码
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Success</h1>
</body>
</html>
运行结果

有状态的会话:一个同学来过教室下次再来教室,我们会知道这个同学曾经来过,称之为有状态会话
一个网站,怎么证明你来过?
服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了;cookie
服务器登记你来过了,下次你来的时候我来匹配你;session
package com.tang.cookie;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
//保存用户上一次访问的时间
public class CookieDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器告诉你,你来的时间,把这个时间封装成一个信件,你下次带来,我就知道你来了
//解决中文乱码
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
//Cookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies();//这里返回数组,说明Cookie可能存在多个
//判断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 l = Long.parseLong(cookie.getValue());//将一个字符串类型的时间戳转换为长整型数据
Date date = new Date(l);//将时间戳转化为日期
out.write(date.toLocaleString());//将一个日期转化为字符串,并写出
//解码
//out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));
}
}
}else{
out.write("这是您第一次访问本站");
}
//服务器给客户端响应一个cookie,System.currentTimeMillis()得到的是从1970年1月1日到今天所获得的时间戳,单位为毫秒
//编码:中文传输尽量这样传,以防乱码
//Cookie cookie = new Cookie("name", URLEncoder.encode("唐昊","utf-8"));
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
resp.addCookie(cookie);//该方法需要一个Cookie所以就new一个就行
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml中servlet的注册代码就不写了,上面写的带太多变了
运行结果图


并且当你退出浏览器,再次进入后cookie值就会消失,但是如果设置cookie的生存期的话,即使退出浏览器,cookie的值任然存在,设置生存期的方法
//cookie有效期为1天,里面存储的单位是秒,因此要计算一天有多少秒
cookie.setMaxAge(24*60*60);
cookie的细节问题:
一个cookie只能保存一个信息;
一个web站点可以给浏览器发送多个cookie,最多存放20个cookie;
cookie大小有限制为4kb
300个cookie浏览器上限
删除Cookie
不设置有效期,关闭浏览器,自动失效
设置有效期时间为0;
编码解码:
//编码:中文传输尽量这样传,以防乱码
Cookie cookie = new Cookie("name", URLEncoder.encode("唐昊","utf-8"));
//解码
out.write(URLDecoder.decode(cookie.getValue(),"utf-8"));
服务器技术,利用这个技术,可以保存用户的会话信息,我们可以吧信息或者数据放在Session中
服务器会给每一个用户(浏览器)创建一个Session对象;
一个Session独占一个浏览器,只要浏览器没有关闭,这个session就存在
用户登录之后,整个网站它都可以访问 -->保存用户的信息:保存购物车的信息....
Session 和Cookie的区别:
Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
Session把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
Session对象由服务创建
使用Session
SessionDemo代码如下
package com.tang.session;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class SessionDemo extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setCharacterEncoding("UTF-8");
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html");
//得到session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name",new Person("唐三",23));
//获取Session的ID
String sessionId = session.getId();
//判断session是不是新创建的
if(session.isNew()){
resp.getWriter().write("session创建成功,ID为:"+sessionId);
}else{
resp.getWriter().write("session在服务器中已经存在了,ID为:"+sessionId);
}
//Session创建的时候自动做了如下的事情
// Cookie cookie = new Cookie("JSESSIONID",sessionId);
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
获取Session里面存的数据
SessionDemo02
package com.tang.session;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import java.io.IOException;
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
resp.setCharacterEncoding("UTF-8");
req.setCharacterEncoding("UTF-8");
resp.setContentType("text/html");
//得到session
HttpSession session = req.getSession();
Person person = (Person) session.getAttribute("name");
System.out.println(person.toString());
resp.getWriter().write(person.toString());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
运行结果图

手动注销Session
注:注销的原理就是将其SessionID给注销,注销后再次访问会分配一个新的SessionID
package com.tang.session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销Session
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
会话自动失效:web.xml代码,注册的代码就不展示了
<!-- 设置Session默认失效时间-->
<session-config>
<!-- 1分钟后,Session失效,以分钟为单位-->
<session-timeout>1</session-timeout>
</session-config>
是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou
我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur
1.错误信息:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:requestcanceledwhilewaitingforconnection(Client.Timeoutexceededwhileawaitingheaders)或者:Errorresponsefromdaemon:Gethttps://registry-1.docker.io/v2/:net/http:TLShandshaketimeout2.报错原因:docker使用的镜像网址默认为国外,下载容易超时,需要修改成国内镜像地址(首先阿里
Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba
我正在使用Heroku(heroku.com)来部署我的Rails应用程序,并且正在构建一个iPhone客户端来与之交互。我的目的是将手机的唯一设备标识符作为HTTPheader传递给应用程序以进行身份验证。当我在本地测试时,我的header通过得很好,但在Heroku上它似乎去掉了我的自定义header。我用ruby脚本验证:url=URI.parse('http://#{myapp}.heroku.com/')#url=URI.parse('http://localhost:3000/')req=Net::HTTP::Post.new(url.path)#boguspara
我试图在我的网站上实现使用Facebook登录功能,但在尝试从Facebook取回访问token时遇到障碍。这是我的代码:ifparams[:error_reason]=="user_denied"thenflash[:error]="TologinwithFacebook,youmustclick'Allow'toletthesiteaccessyourinformation"redirect_to:loginelsifparams[:code]thentoken_uri=URI.parse("https://graph.facebook.com/oauth/access_token
我是Ruby的新手。我试过查看在线文档,但没有找到任何有效的方法。我想在以下HTTP请求botget_response()和get()中包含一个用户代理。有人可以指出我正确的方向吗?#PreliminarycheckthatProggitisupcheck=Net::HTTP.get_response(URI.parse(proggit_url))ifcheck.code!="200"puts"ErrorcontactingProggit"returnend#Attempttogetthejsonresponse=Net::HTTP.get(URI.parse(proggit_url)
我正在尝试解析网页,但有时会收到404错误。这是我用来获取网页的代码:result=Net::HTTP::getURI.parse(URI.escape(url))如何测试result是否为404错误代码? 最佳答案 像这样重写你的代码:uri=URI.parse(url)result=Net::HTTP.start(uri.host,uri.port){|http|http.get(uri.path)}putsresult.codeputsresult.body这将打印状态码和正文。
我正在安装gitlabhq,并且在Gemfile中有对某些资源的“git://...”的引用。但是,我在公司防火墙后面,所以我必须使用http://。我可以手动编辑Gemfile,但我想知道是否有另一种方法告诉bundler使用http://作为git存储库? 最佳答案 您可以通过运行gitconfig--globalurl."https://".insteadOfgit://或通过将以下内容添加到~/.gitconfig:[url"https://"]insteadOf=git://
我希望访问我机器上的所有HTTP流量(我的Windows机器-不是服务器)。据我了解,拥有一个本地代理是所有流量路线的必经之路。我一直在谷歌搜索但未能找到任何资源(关于Ruby)来帮助我。非常感谢任何提示或链接。 最佳答案 WEBrick中有一个HTTP代理(Rubystdlib的一部分)和here's一个实现示例。如果你喜欢生活在边缘,还有em-proxy伊利亚·格里戈里克。这postIlya暗示它似乎确实需要一些调整来解决您的问题。 关于ruby-如何捕获所有HTTP流量(本地代理)