以上就是我们需要实现的功能,使用httpclient实现下拉列表的动态填充!!!本案例是基于springboot实现需要有一定的使用基础,使用spring来实现的话相对来说比较麻烦,我们都知道html实现异步请求,可以使用ajax,那么我们java需要后台实现异步请求可以使用httpclient实现,本案例的实现思路如下
1.select实现change事件
2.用ajax将当前选中的城市传给controller
3.controller使用httpclient调用高德地图获取到区县信息
4.responsebody响应ajax请求,
5.将区县列表填充到第二个下拉框
目结构如下
首先建立springboot项目,不知道怎么小伙伴可以参考,本系列教程第一篇springboot入门案例!!
第一种方式:使用httpClient实现
第一步、在pom中导入本次需要的坐标依赖
本案例使用了,springboot里面特定支持的热部署,不用修改了项目之后不用再次,启动项目,只需要点击idea上面的那个锤子就可以
实现热部署很很简单,只是在pom文件中导入以下坐标就好
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional><!--不能被其它模块继承--> <scope>runtime</scope><!--只在运行时起作用,打包时不打进去--> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.5</version>
</dependency>
<!--这个是将对象转换为字符串-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit4</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>layui</artifactId>
<version>2.4.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional><!--实现热部署,不能被其它模块继承-->
<scope>runtime</scope><!--只在运行时起作用,打包时不打进去-->
</dependency>
</dependencies>
</project>
第二步、编写index.html访问主页面
前台的访问页面是用的ajax请求实现的,向我们的后台的controller传递了一个keysword值,在controller页面进行接收
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<!--导入jquery数据包-->
<script src="webjars/jquery/3.4.1/jquery.min.js"></script>
<style type="text/css">
#div1{
margin: 30px auto;
width: 300px;
height: 20px;
border: 0px solid red;
}
</style>
</head>
<body>
<div id="div1">
省份:
<select id="province">
<option value=" ">--请选择城市--</option>
<option value="重庆">重庆</option>
<option value="北京">北京</option>
</select>
市区:
<select id="district">--省份--</select>
</div>
<script>
$("#province").change(function () {
var province=$("#province").val();//获取选中的值
$("#district").children().remove();//清空前一次访问数据
$.getJSON("doGetControllerOne?keywords="+province,province,function(data){
var result=data.districts[1].districts;
$(result).each(function (i,item) {
var code=item.citycode;
var name=item.name;
$("#district").append("<option value="+code+">"+name+"</option>")
});
});
})
</script>
</body>
</html>
第三步、编写controler控制页面
这里有几点需要详细讲解的地方,这里涉及到了高德api接口的调用,不会使用的小伙伴们可以参考我的另外一篇博客,高德地图入门案例,里面有比较详细的讲解
https://restapi.amap.com/v3/config/district?key=key值&keywords="+keywords+"&subdistrict=1&extensions=base,这个访问的地址https://lbs.amap.com/api/webservice/guide/api/district/获取该以上地址,key值是需要你自己去申请
keyword里面可以修改,然点击运行可以生成新的地址,复制到你的new HttpGet里面
package com.cc.springhttpclient.controller;
import org.apache.http.HttpEntity;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.util.EntityUtils;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class doGet {
@ResponseBody
@RequestMapping("/doGetControllerOne")
public String doGetController(HttpServletRequest req, HttpServletResponse rep){
String keywords=req.getParameter("keywords");
if(StringUtils.isEmpty(keywords)){
keywords="重庆";
}
System.out.println("省份为:"+keywords);
// 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
// 创建Get请求,里面需要放请求的
HttpGet httpGet = new HttpGet("https://restapi.amap.com/v3/config/district?key=填写你的key值&keywords="+keywords+"&subdistrict=1&extensions=base");
// 响应模型
CloseableHttpResponse response = null;
try {
// 由客户端执行(发送)Get请求
response = httpClient.execute(httpGet);
// 从响应模型中获取响应实体
HttpEntity responseEntity = response.getEntity();
if (responseEntity != null) {
//System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));?第一次使用的时候会关闭流
String result=EntityUtils.toString(responseEntity);//解析json数据
return result;
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (ParseException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
// 释放资源
if (response != null) {
response.close();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
}
这里大家有一点需要注意的地方,就是这个toString方法,为了在控制台测试我是否获取到了高德地图里面区域信息,我在用sou在控制台输出了一下,但是下面框框地方显示流被关闭了,当时我就很疑惑这是怎么回事,然后然后点开了toString的源码一下就明白了!!!
public static void consume(HttpEntity entity) throws IOException { if (entity != null) { if (entity.isStreaming()) { InputStream inStream = entity.getContent(); if (inStream != null) { inStream.close(); } } } }
这是toString里面的源码,使用了这个方法之后,流就被关闭了,所以大家在使用这个方法的时候一定要注意!!!!
if (responseEntity != null) { System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));//第一次使用的时候会关闭流 String result=EntityUtils.toString(responseEntity);//解析json数据 return result; }
第四步、启动测试主类
需要完整项目案例的可以去我的github上面下载,以下是我的github地址
https://github.com/chenduotang/spring_boot-httpclient
第二种方式:使用RestTemplate实现
那么RestTemplate和httpclient有什么区别!!说白了就是对,httpclient的进一步高级封装,想了解更多有关RestTemplate可以查看这篇博客
https://blog.csdn.net/u012702547/article/details/77917939/
首先、在config文件中再配置一个RestTemplate的类,交给spring管理
package com.cc.springhttpclient.RestConfig; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; @Configuration public class RestConfig { @Bean public RestTemplate restTemplate(){ RestTemplate restTemplate = new RestTemplate(); return restTemplate; } }
其次、在controller层修改代码如下
package com.cc.springhttpclient.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.client.RestTemplate; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /*** * 第二种实现方式,使用RestTemplate实现 * RestTemplate是对HttpClient的进一步封装 */ @Controller public class doGeto { @Autowired private RestTemplate restTemplate; @ResponseBody @RequestMapping("/doGetControllerOnet") public String doGetController(HttpServletRequest req, HttpServletResponse rep){ String keywords=req.getParameter("keywords"); System.out.println(keywords); if(StringUtils.isEmpty(keywords)){ keywords="重庆"; } String URL="https://restapi.amap.com/v3/config/district?key=你申请的key值&keywords="+keywords+"&subdistrict=1&extensions=base"; String result = restTemplate.getForObject(URL, String.class); return result; } }