JavaWeb02Servlet的编码,继承关系和service方法,HTTP协议,会话Session,服务器转发和客户端重定向

Servlet的编码

之前我们对前端传过来的数据进行插入用的是英文,我们现在用中文来试一下

 

 

 数据库乱码了,所以我们要再dopost获取参数之前就要设置编码

        req.setCharacterEncoding("UTF-8");
        String fname = req.getParameter("fname");

        String priceStr = req.getParameter("price");
        Integer price = Integer.parseInt(priceStr);

        String fcountStr = req.getParameter("fcount");
        Integer fcount = Integer.parseInt(fcountStr);

        String remark = req.getParameter("remark");

        System.out.println(fname);
        System.out.println(price);
        System.out.println(fcount);
        System.out.println(remark);

现在:

 

 数据库插入的就是中文了

补充:

Servlet继承关系

相关方法:

servlet里的service是自动调用的,那么这个方法干了什么呢?我们进入源码查看

servlet里方法是抽象的,我们向下一层看

public interface Servlet {
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

    void destroy();
}

GenericServlet里的service方法还是抽象的,我们向下一层看
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
    
    public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    
}

 httpservlet里的service终于不是抽象的了

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String method = req.getMethod();
        long lastModified;
        if (method.equals("GET")) {
            lastModified = this.getLastModified(req);
            if (lastModified == -1L) {
                this.doGet(req, resp);
            } else {
                long ifModifiedSince;
                try {
                    ifModifiedSince = req.getDateHeader("If-Modified-Since");
                } catch (IllegalArgumentException var9) {
                    ifModifiedSince = -1L;
                }

                if (ifModifiedSince < lastModified / 1000L * 1000L) {
                    this.maybeSetLastModified(resp, lastModified);
                    this.doGet(req, resp);
                } else {
                    resp.setStatus(304);
                }
            }
        } else if (method.equals("HEAD")) {
            lastModified = this.getLastModified(req);
            this.maybeSetLastModified(resp, lastModified);
            this.doHead(req, resp);
        } else if (method.equals("POST")) {
            this.doPost(req, resp);
        } else if (method.equals("PUT")) {
            this.doPut(req, resp);
        } else if (method.equals("DELETE")) {
            this.doDelete(req, resp);
        } else if (method.equals("OPTIONS")) {
            this.doOptions(req, resp);
        } else if (method.equals("TRACE")) {
            this.doTrace(req, resp);
        } else {
            String errMsg = lStrings.getString("http.method_not_implemented");
            Object[] errArgs = new Object[]{method};
            errMsg = MessageFormat.format(errMsg, errArgs);
            resp.sendError(501, errMsg);
        }

    }

我们发现这里面是获取到了请求方式,再执行对应操作,我们看看如果是post,会干什么

protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String msg = lStrings.getString("http.method_post_not_supported");
        this.sendMethodNotAllowed(req, resp, msg);
    }

那么,如果我们在我们的代码里重写dopost,但是请求方式是get会发生什么事情?

已经知道客户端默认向服务器发请求是get,我们只写dopost

public class ServletRelation extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }
}

web.xml

    <servlet>
        <servlet-name>ServletRelation</servlet-name>
        <servlet-class>com.LALALA.servlets.ServletRelation</servlet-class>
    </servlet>
    <servlet-mapping>

        <servlet-name>ServletRelation</servlet-name>
        <url-pattern>/test</url-pattern>
    </servlet-mapping>

tomcat:

 

结果:

 为什么会是405????

我们现在没有doget,会调用父类中的doget,也就是httpservlet里的doget

if (lastModified == -1L) {
    this.doGet(req, resp);

我们看看这个doget干了什么

这边就会返回我们的错误编码和信息

Servlet的生命周期

我们自己重写看一下流程

public class ServletLife extends HttpServlet {
    @Override
    public void init() throws ServletException {
        System.out.println("init..............");
    }

    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        System.out.println("service...........");
    }

    @Override
    public void destroy() {
        System.out.println("destroy............");
    }
}

 

 此时我们访问demo02,我们发现

此时servlet只会初始化一次,无论再怎么刷新页面,都会进行service

在关闭服务器的时候会进行销毁

 

 

 好处:提高系统的启动速度

坏处:第一次请求时,耗时会非常长

我们可以通过设置servlet的初始化时机

数字越小,启动的越早

此时在启动的时候已经完成了初始化

 

 什么是单例的?

此时我们的项目结构无论是relation还是life都是初始化一个servlet来进行实现我们的操作,这就是单例的

什么是线程不安全的?

 和之前JDBC的事务问题类似

 

 

 

HTTP协议

 

会话Session

之前我们说HTTP协议是无状态的,什么意思?

 

 

 

 下面我们来代码验证一下

public class ServletSession01 extends HttpServlet {
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        HttpSession session = request.getSession();
        System.out.println("Session ID:::"+session.getId());
    }
}
    <servlet>
        <servlet-name>ServletSession01</servlet-name>
        <servlet-class>com.LALALA.servlets.ServletSession01</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletSession01</servlet-name>
        <url-pattern>/demo03</url-pattern>
    <servlet-mapping>

调用demo03页面后

 

 我们发现前端会收到一个响应头,里面的setsession和我们控制台收到的一样,这是第一次,服务器给客户端创建了一个sessionID

如果我们这个时候再刷新页面,sessionID还是不会改变,并且服务器不会给这个会话创建新的ID

此时服务器发送请求会带着自己的会话ID在请求头里给服务器

 

 

Session保存作用域

我们可以向session里保存一些数据,为了使我们保存的数据不冲突,我们需要session保存作用域,也就是会话1保存的内容不能被会话2访问

public class ServletSession02 extends HttpServlet {
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        request.getSession().setAttribute("uname","LALALA");

    }
}
public class ServletSession03 extends HttpServlet {
    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        HttpServletRequest request = (HttpServletRequest) req;
        Object uname = request.getSession().getAttribute("uname");
        System.out.println(uname);

    }
}
    <servlet>
        <servlet-name>ServletSession02</servlet-name>
        <servlet-class>com.LALALA.servlets.ServletSession02</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletSession02</servlet-name>
        <url-pattern>/demo04</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ServletSession03</servlet-name>
        <servlet-class>com.LALALA.servlets.ServletSession03</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ServletSession03</servlet-name>
        <url-pattern>/demo05</url-pattern>
    </servlet-mapping>

演示:
先访问demo04再访问demo05

可以正常输出我们设置的值

那么如果先访问04,再换个浏览器访问05会如何?

 

此时换浏览器访问05不能获取

 所以这个保存域中的东西是靠sessionid来区分保存的

服务器转发和客户端重定向

服务器转发:

 客户端重定向:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值