栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Servlet的日常开发(基于场景)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Servlet的日常开发(基于场景)

接:HTTP协议和Web服务器的使用​​​​​​

一、@WebServlet(...)填写的资源路径的问题

1.括号内的路径必须以“/”开头(特殊情况除外)

2.路径不能重复

3.正常情况:"/hello" "/hello/world" "/hello.html" "/hello.jpg"

4.几个特殊情况

1)通配符:"*.do":只要路径后缀名是.do的url都归我管

此时访问:lifecycle.do、a/b.do....等都可以访问到,只要是以.do结尾的都可以访问到。

2)"/":所有的url都归我管(但是精确过的如/liftcycle等的会正常走它的,不归我管,其他没有的url都归我管)

3)"":代表根url

访问http://127.0.0.1:8080 是可以访问到的

什么情况下tomcat会启动失败:

1)端口被占用

2)动态资源的绑定路径有错误时

二、响应体是文本内容并且字符集编码是utf-8的场景

需要做:

1.设置字符集编码

2.设置Content-type的响应头

3.写响应体

不用调用setHead("Content-type","..."),直接:

public class WriteResponse extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/plain");//可以省略";charset="utf-8",会自动补上
        //先设置字符集再getWriter(),否则还会乱码
        PrintWriter writer = resp.getWriter();

        writer.print("1");
        writer.println("12");
        writer.printf("123");
    }
}
三、读取请求参数(params)—读取网页中收集到的用户信息

GET方法的参数放在查询字符串query string中

POST方法的参数放在query string和request body中(ps:必须是form表单提交的POST请求【请求的Content-type必须是application/x-www-form-urlencoded类型】)

通过req.getParameters(...)系列读取(对于GET和POST,我们的代码采用相同的方式读取)

1.GET请求的读取

准备send-param.html:




    
    Title


  
//读取Get请求
@WebServlet("/get-param")
public class GetParam extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }
}

提交后得到:http://127.0.0.1:8088/first-webapp/get-param?username=123&password=123456,验证了请求的name是放在query String中的。

当GET请求时总结:

1)请求参数放在URL的query string中,格式是name=value&name=value

2)value是中文还是英文都可以正常读取

3)如果只有name没有value,读到的是一个空的字符串""

4)如果连name都没有,读到的是null

2.POST请求的读取

    
//读取POST请求
@WebServlet("/post-param")
public class PostParam extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("|"+username+"|");
        System.out.println("|"+password+"|");
    }
}

​

      提交后,根据Content-Length有值知道存在请求体(tomcat在解析时不知道请求体的字符集编码是什么,只能按照默认字符集编码(不是utf-8),所以中文提交后的结果有问题:

​

所以需要设置请求的字符集编码):

@WebServlet("/post-param")
public class PostParam extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");//设置请求的字符集编码(需要加上这步)
//        req.setCharacterEncoding("utf-8");//设置响应的字符集编码(只是用来和上一步对比一下)
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println("|"+username+"|");
        System.out.println("|"+password+"|");
    }
}

      对于post请求,参数可以在form表单,也可以在查询字符串中:

​

​

POST请求时总结:

1)请求参数可以放在url的query string中,也可以放在请求体request body中(前提必须是form表单提交),格式都是name=value&name=value形式

2)value是英文没问题,但是中文有问题,所以读取前应设置请求的字符集编码:req.setCharacterEncoding(...)

3)如果只有name没有value,读到的是一个空的字符串""

4)如果连name都没有,读到的是null

建议标准的读取参数代码如下:
//get和post请求的读取(:统一格式)
public class StandParam extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");//虽然对get没用,但是写上也没有副作用
        String username = req.getParameter("username");
        //String.trim():去除字符串两边的空格
        if(username==null||username.trim().isEmpty()){
            //用户没有填写正确信息,进行一定的错误处理
            //比如:响应400或者重定向到其他页面
        }
        //正常使用username
        //读取到的value一定是String类型,如果需要其他类型,比如int,需要使用Integer.parseInt(str)进行转换
          //但是转换可能异常:Integer.parsetInt("hello")就会异常

        //如果还有其他严格的格式要求,需要自行写代码处理
    }
}
3.GET方法和POST方法的区别⭐⭐

1.根本区别:语义不同,GET代表的获取的语义,POST代表提交的语义

具体表现上的不同:

2.标准中规定:GET不应该带有请求体,POST可以带有请求体

3.有请求参数的话,GET请求放在查询字符串中,POST请求放在查询字符串或请求体(form表单)中。

      由于各个浏览器的实现,url长度限制(1000个字符)短于请求体限制(无限制),所以有说法POST可以带的参数多,GET带的少,但实际上这种说法不准确,这完全是实现上的问题,标准上没有任何规定。

      URL一般会记录在日志中,请求体不会记录,所以还有种说法:POST比GET稍微安全一点,但其实本质是都不安全的,如果真正要安全:使用HTTPS协议

4.将HTTP方法类比成SQL动作:GET方法可以类比成select语句【GET(select)】、POST(insert)、PUT(update)、DELETE(delete)——restful上有这样的建议

所以有:GET和PUT是幂等的,GET无副作用,PUT有副作用;POST不是幂等的;DELETE无副作用

      4.1:幂等和副作用是两个约束限制等级:无副作用>幂等【无副作用一定幂等,幂等不一定没有副作用】

    4.2:幂等:执行select,只要背后的数据不变,得到的结果一定不变,如select*from 表 where.name='xx';只要数据不变,永远执行下去得到的结果一定一致0,这就叫做幂等的。所以insert为什么不幂等:同一个数据/语句,第一次插入成功,但以后插入也可能插入失败。

     4.3:无副作用:执行不会影响数据,叫做无副作用

现象1:GET请求直接刷新浏览器,浏览器就自动重新发送请求了(GET没有副作用),POST请求刷新浏览器有些浏览器会提示用户你确定要重新发送一次POST请求吗

现象2:HTTP请求是支持缓存的(Cache),为了提升访问速度。但是,GET请求支持缓存(因为它没有副作用),POST请求不支持缓存(因为有副作用)

四、资源重定向(redirect)

      当我去请求一个资源时,可以要求浏览器去请求另一个资源,类似:买书,买石头记,老板说资源已经不叫石头记了,你应该去买的书叫红楼梦,这是你应该发起一个新的请求买红楼梦,这个过程就是重定向。

重定向通过3XX做到:3XX+响应头:Location(location:定位到...)

1.重定向分类

1)永久重定向:301 Moved Permanently

2)临时重定向:

      注意:临时重定向时,关于重定向的时候是否保留原方法,历史上是没有考虑到这一点的,临时重定向时没有考虑方法保留问题,所以实现的时候,保留也行不保留也行,但大部分浏览器都实现成不保留的了(退化成GET请求)。1.1的规定中,就分成了:保留方法的临时重定向+不保留方法的临时重定向。

      综述,临时重定向有三个状态码:1个历史2.保留的3.不保留的

302Found历史【302约等于303】
303See Other退化成GET
307Temporary Redirection保留原方法的(POST重定向后方法还是POST)

通过代码观察现象:

@WebServlet("/redirect-303")
public class Redirect303 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        redirect(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        redirect(req,resp);
    }
    private void redirect(HttpServletRequest req,HttpServletResponse resp){
        resp.setStatus(303);
        resp.setHeader("Location","/target");//由于没有实现,结果会404
    }
}

关于303,是GET请求时:


    

      发了GET请求出去,GET请求发的是/direct-303,提交后收到的响应状态码是303,响应头种有Location:/target,浏览器自动就发起了/target请求,它的请求也还是GET。

请求开始是POST时:


    

请求变为GET请求,说明POST请求退化了

307时的POST请求:(把resp.setStatus(303)中303改为307,其他不变进行观察)

POST请求还是POST请求,说明保留了原POST方法

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/966937.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号