关于get:RequestMapping-如果-不添加任何条件默认是get还是post

1、@RequestMapping 如果 不增加任何条件,默认是get还是post?如果在应用 @RequestMapping 注解时,没有指定具体的 HTTP 申请办法,那么默认状况下,这个申请映射将会接管 GET、POST、PUT、DELETE、HEAD、OPTIONS 等所有 HTTP 申请办法。例如,上面的 hello 办法就没有指定具体的申请办法: @RequestMapping("/hello")public String hello() { return "Hello, World!";}在这个例子中,/hello 门路将会承受 GET、POST、PUT、DELETE、HEAD、OPTIONS 等所有 HTTP 申请办法。如果须要限定申请办法,能够通过 method 属性来指定具体的申请办法,例如: @RequestMapping(value = "/hello", method = RequestMethod.GET)public String hello() { return "Hello, World!";}在这个例子中,/hello 门路将仅承受 GET 申请办法。 2、设计逻辑的思考HTTP 协定定义了很多申请办法,如 GET、POST、PUT、DELETE、HEAD、OPTIONS 等,每个申请办法都有本人的语义和用处。在 Spring MVC 中,默认状况下,如果在应用 @RequestMapping 注解时没有指定具体的申请办法,那么这个申请映射将会接管所有的 HTTP 申请办法,即 GET、POST、PUT、DELETE、HEAD、OPTIONS 等。 这是因为,在理论开发中,有时候咱们并不分明客户端会应用什么申请办法来拜访咱们的接口,或者咱们须要提供一个接口同时反对多种申请办法。因而,为了兼容多种申请办法,Spring MVC 默认状况下会将 @RequestMapping 注解不指定申请办法时视为所有申请办法都能够解决。 当然,如果咱们须要限度申请办法,能够通过 method 属性来指定具体的申请办法。例如,如果只心愿承受 GET 申请办法,能够应用 @RequestMapping(value = "/hello", method = RequestMethod.GET) 注解。这样,当客户端应用除 GET 申请办法以外的其余申请办法来拜访 /hello 接口时,Spring MVC 将会返回 405 Method Not Allowed 谬误响应。 ...

March 5, 2023 · 1 min · jiezi

nodejs-原生的post和get请求

把今天学到的东西记录一下const http = require('http')// querystring 模块提供用于解析和格式化 URL 查询字符串的实用工具const querystring = require('querystring')const server = http.createServer((req, res) => { // 请求的方式 const method = req.method // 获取完整请求url const url = req.url // url路径 const path = url.split('?')[0] // 解析 get请求的参数 为?后面 所以数组下标为1 const getParams = querystring.parse(url.split('?')[1]) // 设置返回的格式 json格式 res.setHeader('Content-type','application/json') // 返回的数据 const resData = { method, url, path, getParams } // 0.如果是Post请求 if (method === 'POST'){ // 接收数据 let postData = '' // chunk为一点点数据,逐渐积累 req.on('data', chunk => { postData += chunk.toString() }) req.on('end', () => { resData.postData = postData // 在这里返回 因为是异步 res.end( // 返回json字字符串 JSON.stringify(resData) ) }) } // 1. 如果是get请求 if (method === 'GET'){ // 返回 res.end( // 返回json字字符串 JSON.stringify(resData) ) }})server.listen(8000)

May 27, 2019 · 1 min · jiezi

面试经典之http中get与post的区别

GET和POST是HTTP请求的两种基本方法,要说它们的区别,接触过WEB开发的人都能说出一二。最直观的区别就是GET把参数包含在URL中,POST通过request body传递参数。你可能自己写过无数个GET和POST请求,或者已经看过很多权威网站总结出的他们的区别,你非常清楚知道什么时候该用什么。1、常规答案当你在面试中被问到这个问题,你的内心充满了自信和喜悦。你轻轻松松的给出了一个“标准答案”:-GETPOST后退按钮/刷新无害数据会被重新提交(浏览器应该告知用户数据会被重新提交)。书签可收藏为书签不可收藏为书签缓存能被缓存不能缓存编码类型application/x-www-form-urlencoded 只能进行url编码application/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。历史参数保留在浏览器历史中。参数不会保存在浏览器历史中。对数据长度的限制是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。无限制。对数据类型的限制只允许 ASCII 字符。没有限制。也允许二进制数据。安全性与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET !POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。可见性数据在 URL 中对所有人都是可见的。数据不会显示在 URL 中。“很遗憾,这不是我们要的回答!”请告诉我真相。。。2、本质区别如果我告诉你GET和POST本质上没有区别你信吗? 让我们扒下GET和POST的外衣,坦诚相见吧!GET和POST是什么?HTTP协议中的两种发送请求的方法。HTTP是什么?HTTP是基于TCP/IP的关于数据如何在万维网中如何通信的协议。HTTP的底层是TCP/IP。所以GET和POST的底层也是TCP/IP,也就是说,GET/POST都是TCP链接。GET和POST能做的事情是一样一样的。你要给GET加上request body,给POST带上url参数,技术上是完全行的通的。2.1 那么,“标准答案”里的那些区别是怎么回事?在我大万维网世界中,TCP就像汽车,我们用TCP来运输数据,它很可靠,从来不会发生丢件少件的现象。但是如果路上跑的全是看起来一模一样的汽车,那这个世界看起来是一团混乱,送急件的汽车可能被前面满载货物的汽车拦堵在路上,整个交通系统一定会瘫痪。为了避免这种情况发生,交通规则HTTP诞生了。HTTP给汽车运输设定了好几个服务类别,有GET, POST, PUT, DELETE等等,HTTP规定,当执行GET请求的时候,要给汽车贴上GET的标签(设置method为GET),而且要求把传送的数据放在车顶上(url中)以方便记录。如果是POST请求,就要在车上贴上POST的标签,并把货物放在车厢里。当然,你也可以在GET的时候往车厢内偷偷藏点货物,但是这是很不光彩;也可以在POST的时候在车顶上也放一些数据,让人觉得傻乎乎的。HTTP只是个行为准则,而TCP才是GET和POST怎么实现的基本。但是,我们只看到HTTP对GET和POST参数的传送渠道(url还是requrest body)提出了要求。2.2、“标准答案”里关于参数大小的限制又是从哪来的呢?在我大万维网世界中,还有另一个重要的角色:运输公司。不同的浏览器(发起http请求)和服务器(接受http请求)就是不同的运输公司。 虽然理论上,你可以在车顶上无限的堆货物(url中无限加参数)。但是运输公司可不傻,装货和卸货也是有很大成本的,他们会限制单次运输量来控制风险,数据量太大对浏览器和服务器都是很大负担。业界不成文的规定是,(大多数)浏览器通常都会限制url长度在2K个字节,而(大多数)服务器最多处理64K大小的url。超过的部分,恕不处理。如果你用GET服务,在request body偷偷藏了数据,不同服务器的处理方式也是不同的,有些服务器会帮你卸货,读出数据,有些服务器直接忽略,所以,虽然GET可以带request body,也不能保证一定能被接收到哦。好了,现在你知道,GET和POST本质上就是TCP链接,并无差别。但是由于HTTP的规定和浏览器/服务器的限制,导致他们在应用过程中体现出一些不同。2.3、最终boss你以为本文就这么结束了?我们的大BOSS还等着出场呢。。。这位BOSS有多神秘?当你试图在网上找“GET和POST的区别”的时候,那些你会看到的搜索结果里,从没有提到他。他究竟是什么呢。。。GET和POST还有一个重大区别,简单的说:GET产生一个TCP数据包;POST产生两个TCP数据包。也就是说,GET只需要汽车跑一趟就把货送到了,而POST得跑两趟,第一趟,先去和服务器打个招呼“嗨,我等下要送一批货来,你们打开门迎接我”,然后再回头把货送过去。因为POST需要两步,时间上消耗的要多一点,看起来GET比POST更有效。因此Yahoo团队有推荐用GET替换POST来优化网站性能。但这是一个坑!跳入需谨慎。为什么?GET与POST都有自己的语义,不能随便混用。据研究,在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。而在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。并不是所有浏览器都会在POST中发送两次包,Firefox就只发送一次。好了,看到这里之后再也不怕面试官问get与post请求的区别了。

April 9, 2019 · 1 min · jiezi

解决 go get 下载安装 golang.org/x 相关包失败的问题

问题描述当我们使用 go get、go install、go mod 等命令时,会自动下载相应的包或依赖包。但由于众所周知的原因,类似于 golang.org/x/… 的包会出现下载失败的情况。如下所示:$ go get -u golang.org/x/sysgo get golang.org/x/sys: unrecognized import path “golang.org/x/sys” (https fetch: Get https://golang.org/x/sys?go-get=1: dial tcp 216.239.37.1:443: i/o timeout)解决方式那我们该如何解决问题呢?毕竟还要制造 bug 的嘛~手动下载我们常见的 golang.org/x/… 包,一般在 GitHub 上都有官方的镜像仓库对应。比如 golang.org/x/text 对应 github.com/golang/text。所以,我们可以手动下载或 clone 对应的 GitHub 仓库到指定的目录下。mkdir $GOPATH/src/golang.org/xcd $GOPATH/src/golang.org/xgit clone git@github.com:golang/text.gitrm -rf text/.git当如果需要指定版本的时候,该方法就无解了,因为 GitHub 上的镜像仓库多数都没有 tag。并且,手动嘛,程序员怎么能干呢,尤其是依赖的依赖,太多了。设置代理如果你有代理,那么可以设置对应的环境变量:export http_proxy=http://proxyAddress:portexport https_proxy=http://proxyAddress:port或者,直接用 all_proxy:export all_proxy=http://proxyAddress:portgo mod replace从 Go 1.11 版本开始,新增支持了 go modules 用于解决包依赖管理问题。该工具提供了 replace,就是为了解决包的别名问题,也能替我们解决 golang.org/x 无法下载的的问题。go module 被集成到原生的 go mod 命令中,但是如果你的代码库在 $GOPATH 中,module 功能是默认不会开启的,想要开启也非常简单,通过一个环境变量即可开启 export GO111MODULE=on。以下为参考示例:module example.com/hellorequire ( golang.org/x/text v0.3.0)replace ( golang.org/x/text => github.com/golang/text v0.3.0)类似的还有 glide、gopm 等这类第三方包管理工具,都不同方式的解决方案提供给我们。GOPROXY 环境变量终于到了本文的终极大杀器 —— GOPROXY。我们知道从 Go 1.11 版本开始,官方支持了 go module 包依赖管理工具。其实还新增了 GOPROXY 环境变量。如果设置了该变量,下载源代码时将会通过这个环境变量设置的代理地址,而不再是以前的直接从代码库下载。这无疑对我等无法科学上网的开发良民来说是最大的福音。更可喜的是,goproxy.io 这个开源项目帮我们实现好了我们想要的。该项目允许开发者一键构建自己的 GOPROXY 代理服务。同时,也提供了公用的代理服务 https://goproxy.io,我们只需设置该环境变量即可正常下载被墙的源码包了:export GOPROXY=https://goproxy.io也可以通过置空这个环境变量来关闭,export GOPROXY=。对于 Windows 用户,可以在 PowerShell 中设置:$env:GOPROXY = “https://goproxy.io"最后,我们当然推荐使用 GOPROXY 这个环境变量的解决方式,前提是 Go version >= 1.11。参考资料goproxy.io for Go modulesgoproxy.io感谢您的阅读,觉得内容不错,点个赞吧 ????原文地址: https://shockerli.net/post/go… ...

February 24, 2019 · 1 min · jiezi

都9102年了,还问GET和POST的区别

1 前言最近看了一些同学的面经,发现无论什么技术岗位,还是会问到 get 和 post 的区别,而搜索出来的答案并不能让我们装得一手好逼,那就让我们从 HTTP 报文的角度来撸一波,从而搞明白他们的区别。2 标准答案在开撸之前吗,让我们先看一下标准答案长什么样子 w3school: GET 对比 POST。标准答案很美好,但是在面试的时候把下面的表格甩面试官一脸,估计会装逼不成反被*。分类GETPOST后退按钮/刷新无害数据会被重新提交(浏览器应该告知用户数据会被重新提交)。书签可收藏为书签不可收藏为书签缓存能被缓存不能缓存编码类型application/x-www-form-urlencodedapplication/x-www-form-urlencoded 或 multipart/form-data。为二进制数据使用多重编码。历史参数保留在浏览器历史中。参数不会保存在浏览器历史中。对数据长度的限制是的。当发送数据时,GET 方法向 URL 添加数据;URL 的长度是受限制的(URL 的最大长度是 2048 个字符)。无限制。对数据类型的限制只允许 ASCII 字符。没有限制。也允许二进制数据。安全性与 POST 相比,GET 的安全性较差,因为所发送的数据是 URL 的一部分。在发送密码或其他敏感信息时绝不要使用 GET !POST 比 GET 更安全,因为参数不会被保存在浏览器历史或 web 服务器日志中。可见性数据在 URL 中对所有人都是可见的。数据不会显示在 URL 中。注意,并不是说标准答案有误,上述区别在大部分浏览器上是存在的,因为这些浏览器实现了 HTTP 标准。但是,前面列举的只是浏览器实现上的区别,而不是 get 和 post 的本质区别。3 GET 和 POST 报文上的区别先下结论,GET 和 POST 方法没有实质区别,只是报文格式不同。GET 和 POST 只是 HTTP 协议中两种请求方式,而 HTTP 协议是基于 TCP/IP 的应用层协议,无论 GET 还是 POST,用的都是同一个传输层协议,所以在传输上,没有区别。报文格式上,不带参数时,最大区别就是第一行方法名不同POST方法请求报文第一行是这样的 POST /uri HTTP/1.1 \r\nGET方法请求报文第一行是这样的 GET /uri HTTP/1.1 \r\n是的,不带参数时他们的区别就仅仅是报文的前几个字符不同而已带参数时报文的区别呢? 在约定中,GET 方法的参数应该放在 url 中,POST 方法参数应该放在 body 中举个例子,如果参数是 name=chengqm, age=22。GET 方法简约版报文是这样的GET /index.php?name=qiming.c&age=22 HTTP/1.1Host: localhostPOST 方法简约版报文是这样的POST /index.php HTTP/1.1Host: localhostContent-Type: application/x-www-form-urlencodedname=qiming.c&age=22现在我们知道了两种方法本质上是 TCP 连接,没有差别,也就是说,如果我不按规范来也是可以的。我们可以在 URL 上写参数,然后方法使用 POST;也可以在 Body 写参数,然后方法使用 GET。当然,这需要服务端支持。4. 常见问题GET 方法参数写法是固定的吗?在约定中,我们的参数是写在 ? 后面,用 & 分割。我们知道,解析报文的过程是通过获取 TCP 数据,用正则等工具从数据中获取 Header 和 Body,从而提取参数。也就是说,我们可以自己约定参数的写法,只要服务端能够解释出来就行,一种比较流行的写法是 http://www.example.com/user/name/chengqm/age/22。POST 方法比 GET 方法安全?按照网上大部分文章的解释,POST 比 GET 安全,因为数据在地址栏上不可见。然而,从传输的角度来说,他们都是不安全的,因为 HTTP 在网络上是明文传输的,只要在网络节点上捉包,就能完整地获取数据报文。要想安全传输,就只有加密,也就是 HTTPS。GET 方法的长度限制是怎么回事?在网上看到很多关于两者区别的文章都有这一条,提到浏览器地址栏输入的参数是有限的。首先说明一点,HTTP 协议没有 Body 和 URL 的长度限制,对 URL 限制的大多是浏览器和服务器的原因。浏览器原因就不说了,服务器是因为处理长 URL 要消耗比较多的资源,为了性能和安全(防止恶意构造长 URL 来攻击)考虑,会给 URL 长度加限制。POST 方法会产生两个TCP数据包?有些文章中提到,post 会将 header 和 body 分开发送,先发送 header,服务端返回 100 状态码再发送 body。HTTP 协议中没有明确说明 POST 会产生两个 TCP 数据包,而且实际测试(Chrome)发现,header 和 body 不会分开发送。所以,header 和 body 分开发送是部分浏览器或框架的请求方法,不属于 post 必然行为。5 talk is cheap show me the code如果对 get 和 post 报文区别有疑惑,直接起一个 Socket 服务端,然后封装简单的 HTTP 处理方法,直接观察和处理 HTTP 报文,就能一目了然#!/usr/bin/env python# -- coding: utf-8 --import socketHOST, PORT = ‘’, 23333def server_run(): listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) listen_socket.bind((HOST, PORT)) listen_socket.listen(1) print ‘Serving HTTP on port %s …’ % PORT while True: # 接受连接 client_connection, client_address = listen_socket.accept() handle_request(client_connection)def handle_request(client_connection): # 获取请求报文 request = ’’ while True: recv_data = client_connection.recv(2400) recv_data = recv_data.decode() request += recv_data if len(recv_data) < 2400: break # 解析首行 first_line_array = request.split(’\r\n’)[0].split(’ ‘) # 分离 header 和 body space_line_index = request.index(’\r\n\r\n’) header = request[0: space_line_index] body = request[space_line_index + 4:] # 打印请求报文 print(request) # 返回报文 http_response = “”"\HTTP/1.1 200 OK<!DOCTYPE html><html><head> <title>Hello, World!</title></head><body><p style=“color: green”>Hello, World!</p></body></html>""" client_connection.sendall(http_response) client_connection.close()if name == ‘main’: server_run()上面代码就是简单的打印请求报文然后返回 HelloWorld 的 html 页面,我们运行起来[root@chengqm shell]# python httpserver.py Serving HTTP on port 23333 …然后从浏览器中请求看看打印出来的报文然后就可以手动证明上述说法,比如说要测试 header 和 body 是否分开传输,由于代码没有返回 100 状态码,如果我们 post 请求成功就说明是一起传输的(Chrome/postman)。又比如 w3school 里面说 URL 的最大长度是 2048 个字符,那我们在代码里面加上一句计算 uri 长度的代码…# 解析首行first_line_array = request.split(’\r\n’)[0].split(’ ‘)print(‘uri长度: %s’ % len(first_line_array[1]))…我们用 postman 直接发送超过 2048 个字符的请求看看然后我们可以得出结论,url 长度限制是某些浏览器和服务器的限制,和 HTTP 协议没有关系。到此,我们可以愉快地装逼了 :)参考:99%的人都理解错了HTTP中GET与POST的区别关于HTTP GET 和 POSTw3school: HTTP 方法:GET 对比 POSTwikipedia: 超文本传输协议RFC 2068 ...

February 12, 2019 · 2 min · jiezi

redis 使用 get 命令读取 bitmap 类型的数据

在签到统计场景中,可以使用 bitmap 数据类型高效的存储签到数据,但 getbit 命令只能获取某一位值,就无法最优的满足部分业务场景了。比如我们按年去存储一个用户的签到情况,365 天,只需要 365 / 8 ≈ 46 Byte,1KW 用户量一年也只需要 44 MB 就足够了。setbit sign:uid:year 0 1 #第1天setbit sign:uid:year 1 1 #第2天…setbit sign:uid:year 364 1 #第365天但如果我想获取某个用户一年的签到统计,使用 bitget 命令的话…要循环读取 365 次,这是没办法接受的。如果能一次读取到以字符串"1000100010100100…001"的形式表示的位状态数据,就很好做后续的处理了。bitmap 其实也是一种特殊的字符串数据,使用 get 命令是可以读取出来的,但是以 16 进制的流数据返回的,这里就涉及到网络编程中数据传输的打包/解包的知识,redis 使用 get 命令读取 bitmap 数据时,将二进制数据打包成了 16 进制返回给我们,所以我们要对此数据包以 16 进制解包,然后转为二进制字符串。给出转换方法:<?php// 第1天的签到$redis->setBit(‘sign:uid:year’, 0, 1);// 第234天的签到$redis->setBit(‘sign:uid:year’, 233, 1);// 第365天的签到$redis->setBit(‘sign:uid:year’, 364, 1);// 使用 get 命令一次性读取用户的 bitmap 签到数据$bitmap_str = $redis->get(“sign:uid:year”);// 对数据流使用网络字节序(大端)解包拿到16进制数据的字符串形式$hex_str = unpack(“H*”, $bitmap_str)[1];// hex str 的长度$hex_str_len = strlen($hex_str);// 为了防止 hex to dec 时发生溢出// 我们需要切分 hex str,使得每一份 hex str to dec 时都能落在 int 类型的范围内// 因为 2 位 16 进制表示一个字节,所以用系统 int 类型的字节长度去分组是绝对安全的$chunk_size = PHP_INT_SIZE;// 对 hex str 做分组对齐,否则 str 的最后几位可能会被当作低位数据处理// 比如 fffff 以 4 位拆分 ‘ffff’, ‘f’ 后 最后一组 ‘f’ 就被低位数据处理了// 对齐后 fffff000 分组 ‘ffff’, ‘f000’ 就能保证 ‘f’ 的数据位了$hex_str = str_pad($hex_str, $hex_str_len + ($chunk_size - ($hex_str_len % $chunk_size)), 0, STR_PAD_RIGHT);// 防止 hexdec 时溢出 使用 PHP_INT_SIZE 个 16 进制字符一组做拆分// 因 16 进制 2 位标识一个字节 所以 PHP_INT_SIZE 是绝对不会溢出的$hex_str_arr = str_split($hex_str, $chunk_size);// 位数据的二进制字符串$bitmap_bin_str = ‘’;array_walk($hex_str_arr, function($hex_str_chunk) use (&$bitmap_bin_str, $chunk_size) { $bitmap_bin_str .= str_pad(decbin(hexdec($hex_str_chunk)), $chunk_size * 4, 0, STR_PAD_LEFT);});// 一次读取redis即可拿到 bitmap O(n)次操作的数据echo $bitmap_bin_str{0} . PHP_EOL; //第1天echo $bitmap_bin_str{233} . PHP_EOL;//第234天echo $bitmap_bin_str{364} . PHP_EOL;//第365天注释较多,业务代码不多,多多理解~ ...

December 21, 2018 · 1 min · jiezi

在yii2中,让你action参数支持POST数据的小方法

我们先来看一段代码class RaController extends Controller { public $enableCsrfValidation = false; public function actionSay($username = ‘’,$city = ‘’){ echo “{$username} 来自 {$city}”; }}这里actionSay对应的url为index.php?r=ra/say,而 $username 和 $city 值的获取来自于url的参数,比如index.php?r=ra/say&username=abei2017&city=洛阳总结 在yii2中,action参数都是来自于GET。但是有的时候你可能需要让action的参数来自于POST请求,怎么办?重载runAction即可,yii2为控制器提供了runAction方法,它负责生成一个具体的Action对象并传递参数,我们可以通过复写它来实现,你可以看下yii2的生命周期来对其进行更好的了解。那就开始干吧~,对上面的代码复写runActionclass RaController extends Controller { public $enableCsrfValidation = false; public function runAction($id, $params = []){ $params = ArrayHelper::merge(Yii::$app->request->post(),$params); return parent::runAction($id, $params); } public function actionSay($username = ‘’,$city = ‘’){ echo “{$username} 来自 {$city}”; }}复写了runAction后,它将作用于此控制器的所有action,当然你也可以通过runAction的$id来作用于某个action。比如public function runAction($id, $params = []){ if($id == ‘say’){ $params = ArrayHelper::merge(Yii::$app->request->post(),$params); } return parent::runAction($id, $params);}现在去试试吧,对say动作提交POST数据username和city,成功接收。 ...

September 26, 2018 · 1 min · jiezi