前前后后花了好几个月的时间学习Java基础,感觉都是零零散散的知识点,不仅不知道实际当中怎么用,而且容易忘。所以,开始一个真正的应用很有必要,不仅可以整合前面所学的知识,更重要的是开始接触真正的工作内容。
一个基本的Spring项目包括:
pom.xml文件 src/main/java/hello/Application.java src/main/java/hello/HelloController.java
pom(project-object-model),maven的配置文件,也是Java项目的核心文件。首先,按照官网的 提示 ,在一个空的文件夹中新建 pom.xml
文件,然后将 Build With Maven 中的内容粘贴到其中。
Application以及HelloController,同样按照提示将代码复制到其中。 刷新Maven 后,就可以发现这时候这个项目以及可以开始运行了。并且在浏览器中输入 lcoalhost:8080
就可以看到这个项目已经启动了:
例如:我们在谷歌浏览器搜索栏中填入 springboot
这时可以看到url变成了 https://www.google.com/search?q=springboot&oq=springboot&aqs=chrome..69i57l2j69i60j69i61j69i60l2.2979j0j7&sourceid=chrome&ie=UTF-8
那么 ?
后面这一系列的键值对就都称为查询字符串。补充说明一下:search在产品维度上称为接口。
响应内容包括:
补充说明:
假设我们是Google,用户输入这样一个网址 http://localhost:8080//search?q=dog
,那么我们要怎么拿到这个 dog
关键字呢?回到代码中:
//将接口名指定为/search @RequestMapping("/search") //请求的参数指定为q public String search(@RequestParam("q") String searchKeyWord) { return "you are searching:"+searchKeyWord; } 复制代码
重新点击运行,输入网址:
可以看到这时候我们就拿到用户请求的关键字了。但是从前面Google的url请求中可以看出,实际上url中携带的请求参数肯定不止一个,并且用户肯定是不知道serach接口中存在多少个参数,那么如何设置多个参数,并设置默认不需要赋值? 代码如下:
@RequestMapping("/search") //将charset参数设置为非强制的 public String search(@RequestParam("q") String searchKeyWord, @RequestParam(required = false,value = "charset") String charset) { return "you are searching:"+searchKeyWord + " with charset is :"+charset; } 复制代码
GET请求通常用于传递非敏感信息,因为在GET请求中的账户名密码都是会显示在url中的,所以不能将敏感信息通过GET请求发送。
RESTful API是一套用于设计WEB数据接口的一套API设计规范,用以规范URL、状态码以及服务器的响应。 developer.github.com/v3/ (github的API被称为业界的标杆,值得学习)。
方法中的参数获取
以DELETE举例,spring中的代码如下:
@RestController //把所有的请求映射到一个方法上 @RequestMapping("repos") public class IssueController { @DeleteMapping("/{owner}/{repo}/issues/{issuesNumber}/lock") public void unlock( @PathVariable("owner") String owner, @PathVariable("repo") String repo, @PathVariable("issuesNumber") String issueNumber ) { System.out.println(owner+" "+repo+" "+issueNumber); } } 复制代码
由于DELETE操作不能由浏览器发起,这里使用 Postman 模拟DELETE请求。
在控制台中可以看到输出信息:
这样便实现了第二种请求中参数的获取,既从路径中获取参数。
当请求的参数非常多时,一般都是将参数至于HTTP post的body中,那么如何从HTTP的body中拿到参数呢?同样以GitHub的POST举例:
请求的路径为POST /repos/:owner/:repo/issues
body为:
{ "title": "Found a bug", "body": "I'm having a problem with this.", "assignees": [ "octocat" ], "milestone": 1, "labels": [ "bug" ] } 复制代码
代码如下:
@PostMapping("/{owner}/{repo}/issues") public void createAnIssue( @PathVariable("owner") String owner, @PathVariable("repo") String repo, @RequestBody HashMap requestBody ){ System.out.println(requestBody); } 复制代码
同样使用PostMan模拟post请求: url: http://localhost:8080/repos/hello/world/issues
body:
注意,这时候需要设置header:
否则spring是识别不出JSON的。
通过调试看到:
可以看到,我们把post的body中的参数拿出来了,但是使用LinkedHashMap来存储参数,获取参数不是那么方便,我们可以生成一个内部类来存储。使用插件 GsonFormat 可以代替我们做这件事情:
具体操作:
新建一个类->alt+insert->Gsonformat->将JSON字符粘贴至其中->点击确定即可。
结果如下:PostBody{title='Found a bug', body='I'm having a problem with this.', milestone=1, assignees=[octocat], labels=[bug]}
。
代码如下:
@PostMapping("/getForm") public void getForm( @RequestParam("name") String name, @RequestParam("city") String city ){ System.out.println(name); System.out.println(city); } 复制代码
post请求如下:
结果:
zhangsan beijin 复制代码
可以看到,实现了从form表单中获取参数,这种方式适用于参数比较少的情况。
通过前面的几种方式,我们拿到了HTTP请求中的参数,接下来就是作出合理的处理,然后生成HTTP响应给前端了。
首先我们知道,HTTP响应返回的本质上就是一个HTML文本,使用一些标记语言实现对结果的美化。所以最简单的操作,我们也可以在Java代码中直接添加HTML标签:
@RequestMapping("/getForm") public String getForm( @RequestParam("name") String name, @RequestParam("city") String city ) { //为返回结果添加标签 return ("<em>" + name + "</em>" + " " + "<strong>" + city + "</strong>"); } 复制代码
结果:
也可以直接操作HttpServletResponse对象(Servlet的核心接口)。
@RequestMapping("/Servlet") public void controlRawServlet(HttpServletRequest request, HttpServletResponse response) throws IOException { //返回一个status code=403错误 response.setStatus(HttpServletResponse.SC_FORBIDDEN); //将信息写入http reponse中 response.getWriter().write("hello world 403"); } 复制代码
结果如下:
当然,实际运用中是不会用这样简单粗暴的方式的,一般都是格式化的返回一个 JSON
字符串。在Spring中实现往http body中写入数据:
@RequestMapping("/GetBody") @ResponseBody public Object writeIntoBody(){ Map<String,Object> map = new HashMap<>(); map.put("result", Arrays.asList("zhangsan","beijin")); return map; } 复制代码
结果:
注意:返回的文本,默认格式是JSON。但是,如果我们返回一个XML呢?在PostMan中这样设置:
可以看到console显示: HttpMediaTypeNotAcceptableException
意思就是不接受这种返回类型。
其实这就是Spring最基本的实现了,获取一个Http请求返回一个Http reponse。我们需要做的就是在这个基础上继续扩展,包括数据库、Redis缓存、消息队列、以及RPC(Remote Procedure Call-远程过程调用)、微服务化等。
参考自WebTechGarden的个人博客以及stackoverflow的回答:
首先HTTP协议中并没有规定GET中不能带body,并且作者采用多种方式证明了,HTTP GET是可以带body的。但是GET被设计来用URI来识别资源,如果让它的请求体中携带数据,那么通常的缓存服务便失效了,URI 不能作为缓存的 Key。
但另一方面,如果仅仅是为了读取资源,而需要使用 Body 发送一大批数据时,改用 POST 请求却与 RESTFul 的 post 语义不相符。这时候或许可以 GET + body, 但是不能对该请求以 URI 作为 Key 进行缓存了。
所以,在GET中添加body是没有意义的。
摘自: 知乎.来之孤岛的鲸鱼
Java Servlet(Java服务器小程序)是一个基于Java技术的Web组件,运行在服务器端,它由Servlet容器所管理,用于生成动态的内容。 Servlet是平台独立的Java类,编写一个Servlet,实际上就是按照Servlet规范编写一个Java类。Servlet被编译为平台独立 的字节码,可以被动态地加载到支持Java技术的Web服务器中运行。
Servlet容器也叫做Servlet引擎,是Web服务器或应用程序服务器的一部分,用于在发送的请求和响应之上提供网络服务,解码基于 MIME的请求,格式化基于MIME的响应。Servlet没有main方法,不能独立运行,它必须被部署到Servlet容器中,由容器来实例化和调用 Servlet的方法(如doGet()和doPost()),Servlet容器在Servlet的生命周期内包容和管理Servlet。在JSP技术 推出后,管理和运行Servlet/JSP的容器也称为Web容器。
1.个人博客.《谁说 HTTP GET 就不能通过 Body 来发送数据呢?》 跳转至源文章
2. stackoverflow.“HTTP GET with request body” 跳转至源文章
3. 微信公众号: WebTechGarden.《99%的人都理解错了HTTP中GET与POST的区别》 跳转至源文章
4. 个人博客.《RESTful API 最佳实践》 跳转至源文章
5. 知乎.《几个概念:Servlet、Servlet容器、Tomcat》 跳转至源文章