大致流程
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>hello</title> </head> <body> <form action="add" method="post"> 名称<input type="text" name="fname"/><br> 价格<input type="text" name="price"/><br> 库存<input type="text" name="fcount"/><br> 备注<input type="text" name="remake"/><br> <input type="submit" value="添加"/><br> </form> </body> </html>
注:要导入一个包:servlet-api,jar或是点击项目结构
找到自己建额项目
再这样
找到红线画的
//这里要添一点包哦 public class AddServlet extends HttpServlst{ @Override public void doPost(HttpServletRequest request,HttpServletResponse response)throws IOExcepton,ServletExcption{ String fname = request.getParameter("fname"); String priceSrc = request.getParameter("price"); Integer price = Integer.parseInt(priceSrc); //强转一下 String fcountSrc = request.getParameter("fcount"); Integer fcount = Integer.parseInt(fcountSrc); String remake = request.getParameter("remake"); System.out.println("fanme="+fname); System.out.println("price="+price); System.out.println("fcount="+fcount); System.out.println("remake="+remake); } }
<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>AddServlet</servlet-name> <servlet-class>com.servlet.AddServlet</servlet-class> <!--要写全哦--> </servlet> <servlet-mapping> <servlet-name>AddServlet</servlet-name> <url-pattern>/add</url-pattern> </servlet-mapping> </web-app>
基本流程/步骤
<!-- 1.用户发请求,action = add 2.服务器(tomcat)/项目,中web.xml中找到url-pattern = /add 3.找到第11行的servlet-name = AddServlet 4.找和servlet-mapping中servlet-name一致的servlet 5.找到第八行的servlet-class = com.servlet.AddServlet 6.用户发送的post请求(method = post) 因此tomcat会执行AddServlet中的doPost方法 -->
然后执行,如果看了上一篇的视频,并跟的做了的话可能会出现,404
没有关系将之前的Demo01改成自己html文件的名字就可以啦
再点击添加后,就可以再控制台看到这个了
在上个项目中的水果表单添加中文时会出现乱码
在AddServlet中添加(tomcat8之后)
request.setCharacterEncoding("UTF-8");
注:这句代码要在获取参数之前来填写
解决啦
java.servlet.Servlet接口 java.servlet.GenericServlet抽象类 java.servlet.http.HttpServlet抽象子类
void init(config) --初始化方法
void service(request,response) --服务方法
void destory() -- 销毁方法
void service(request,response) -- 仍然是抽象的
void service(request,response) --不是抽象的
1.String method = req.getMethood() -- 获取请求的方式
2.各种if判断,根据请求方式的不同,决定去调用不同的do方法
3.在HttpServlet这个抽象类中,do方法都差不多
来个小例子
//演示Servlet的生命周期 public class Servlet02 extends HttpServlet { @Override public void init() throws ServletException { System.out.println("正在初始化..."); } @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("正在服务..."); } @Override public void destroy() { System.out.println("正在销毁"); } }
<servlet> <servlet-name>Servlet02</servlet-name> <servlet-class>src.com.servlets.Servlet02</servlet-class> </servlet> <servlet-mapping> <servlet-name>Servlet02</servlet-name> <url-pattern>/Demo02</url-pattern> </servlet-mapping>
看看效果:
默认情况下:
- 第一次接收请求时,这个Servlet会进行实例化(调用构造方法),初始化(调用init()),然后服务(调用service()) *提高 服务器的启动速度,第一次请求耗时较长* - 从第二次请求开始,每一次都是服务(点一下刷新,服务一次) - 当容器关闭时,其中的所有的Servlet实例化会被销毁,调用销毁方法
Servlet实例tomcat只会创建一个,所有的请求都是这个实例去响应
因此:如果要提高系统的启动速度,当前默认情况就是这样;如果需要提高响应速度,我们应该设置Servlet的初始化时机
Servlet在容器中是,单例的,线程不安全的(共用一个实例)
-单例:所有请求都是同一个实例去响应
-线程不安全:一个线程需要根据这个实例中的某个成员变量的值去做逻辑判断,但是在中间某个时机,另一个线程 改变了这个成员变量的值,导致第一个线程的执行路径发生了变化
-尽量不要在Servlet中定义成员变量,如果要定义,不要去根据成员便改良的值去做逻辑判断 / 修改成员变量的值
默认是第一次接收请求时,实例化,初始化
我们可以通过
修改之后
Http:Hyper Text transfer Protocol超文本传输协议。确定了请求和响应的数据格式
Http是无状态的
Http请求响应包含两个部分:请求和响应
-请求:请求包含3个部分:1.请求行 2.请求(消息)头 3.请求体 -响应:响应也含3个部分:1.响应行 2.响应(消息)头 3.响应体
作用:展现当前请求的最基本信息
在我刚才的页面上可以查看(F12)
作用:通过具体的参数对本次请求进行详细说明(包含很多客户端需要告诉服务器的信息,eg:我的浏览器型号、版本...)
格式:键值对,键和值之间只用""隔开
作用:作为请求的主体,发送数据给服务器,具体来说其实就是POS请求方法下的请求参数
格式:
包含服务器信息:服务器发送给浏览器的信息(内容的媒体类型、编码...)
响应的实际内容(eg:请求html的内容)
解释Http无状态:服务器无法判断两次(或多次)请求是否是同一个客户端发来的
-实际问题:第一次请求时添加商品到购物车,第二次时结账,若无法区分是否时同一用户发的请求,会导致混乱
-通过会话跟踪技术来解决
request.getSessin() -> 获取当前的会话,没有创一个新的 request.getSession(true) -> 同上 request.getSession(false) -> 获取当前会话,没有则返回null,不会创建新的 session.getId() -> 获取sessionID session。isNew -> 判断当前session是否是新的 session.getMaxInactiveIntervsl() -> session的非激活间隔时长(默认1800s) session.setMaxInactiveIntervsl() session.invalidata() -> 强制让会话立即失效 session.get
小例子(web.xml就不写了,都一样)
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取session,如果获取不到,则创键一个新的 HttpSession session = req.getSession(); System.out.println("sessionID:"+session.getId()); }
1.session保存作用域是和具体的某一个session对应的
2.常用的API
//可以有多个key,但不要重复,一旦重复,会覆盖之前的value void session.setAttribute(k,v); Object session.getAttribute(k); void removeAttribute(k);
大家如果不想实验代码就先跳过下面这一段
两个不同的类哦
//session保存作用域:存储 public class Servlet04 extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.getSession().setAttribute("uname","lina"); }
//session保存作用域:获取(它是Demo05) public class Servlet05 extends HttpServlet { @Override protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Object unameObj = request.getSession().getAttribute("uname"); System.out.println("unameObj:"+unameObj); }
同上web.xml就不写了
最后会在控制台输出 lina(可以尝试换一个浏览器搜索Demo05,结果是null哦)
-是一次请求响应的过程,对于客户端,内部经历了多少次转发,客户端时不知道的
-地址栏没有变化
例子:(注意看红色的线)
-两次请求响应的过程,客户端知道URL有变化
-地址栏有变化
例子: