先来说下我的网站架构吧
前面大家也看到了 既然叫博客搜 自然是搜索 博客的 我把每个网站会抽象成一个Client
上面只是展示了主要部分 像Hystrix Ribbon Zuul等等就不画上去了
下面我们再建一个Client 选Eureka Server就可以了
修改下Application
@EnableEurekaClient
@SpringBootApplication
public class Springtest
public static void main(String[] args) {
SpringApplication.run(Springtest
}
修改下Application.properties
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.application
server.port=8981
新建一个Controller
@RestController
public class @RequestMapping(value ="/search")
public String search(@RequestParam("key") String key,@RequestParam("page") String page) {
return "hello";
}
}
测试下
下面是爬取搜索的接口 ,比较简单 没做什么处理
这里我们引入了 谷歌的GSON 包 方便处理数据
打开pom.xml 在里面加如GSON 引用
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
public class SearchUtil {
public static Gson gson = new Gson();
public static ArrayList<HashMap<String, String>> search(String key,String type,String page) throws Exception {
StringBuffer url =new StringBuffer("https:/url.append(key);
url.append("&t=");
url.append(type);
url.append("&p=");
url.append(page);
url.append("&o=&s=&l=&_=");
url.append(System.currentTimeMillis());
URL serverUrl = new URL(url.toString());
System.out.println(url.toString());
HttpURLConnection conn = (HttpURLConnection) serverUrl.openConnection();
conn.setConnectTimeout(5000);
InputStream in = conn.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in, "UTF-8"));
StringBuffer sb = new StringBuffer();
String line;
while ((line = br.readLine()) != null) {
sb.append(line);
}
Map<String, Object> map = gson.fromJson(sb.toString(), new TypeToken<HashMap<String, Object>>() {
}.getType());
ArrayList<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
ArrayList<LinkedTreeMap<String, String>> mlist = (ArrayList<LinkedTreeMap<String, String>>) map.get("lresult");
HashMap<String, String> m;
for (LinkedTreeMap<String, String> o : mlist) {
m = new HashMap<String, String>();
m.put("title", convertString(o.get("title"),key));
m.put("content", convertString(o.get("digest"),key));
m.put("link", o.get("url"));
list.add(m);
}
return list;
}
public static String convertString(String str,String key) {
// if(key.contains("+")) {
// String[] s = key.split("[+]");
// for (int i = 0; i < s.length; i++) {
// key = s[i];
//// if (str != null) {
//// str = str.replaceAll("<em>", "").replaceAll("</em>", "").replaceAll("amp;", "");
//// }
// str = str.replaceAll("(?i)" + key, "<em>" + key + "</em>");
// }
//
// }
// else {
// if (str != null) {
// str = str.replaceAll("<em>", "").replaceAll("</em>", "").replaceAll("amp;", "");
// }
// str =str.replaceAll("(?i)"+key, "<em>"+key+"</em>");
// }
return str;
}
}
View Code
修改下Controller
@RestController
public class Gson gson = new Gson();
@RequestMapping(value = "/search")
public String search(@RequestParam("key") String key, @RequestParam("page") String page) {
System.out.println("search");
ArrayList<HashMap<String, String>> result;
try {
result = SearchUtil.search(key, "blog", page);
return gson.toJson(result);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
View Code
View Code
重新测试下接口
数据已经有了
我们的端是不直接访问的 , 需要通过Client来访问 下面可以结合下前面做的搜索框了
回到Client项目 我们先新建一个service 用来处理 连接
@Service
public class ClientService {
@Autowired RestTemplate restTemplate;
public String search(String key,String page) {
HashMap<String, String> map = new HashMap<>();
map.put("key", key);
map.put("page", page);
String str= restTemplate.getForObject("http://localhost:8981/search?key={key}&page={page}",String.class,map);
return str;
}
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
}
修改下Client 下面的Controller
@RestController
public class ClientController {
@Autowired
ClientService cs;
@RequestMapping(value ="/search")
public String search(@RequestParam("key") String key,@RequestParam("page") String page) {
return cs.search(key, page);
}
}
修改下我们的index.ftl 就是前面的页面
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
.searchBtn{
background-color:#38f;
color:#fff;
font-size: 16px;
padding-top: 0px;
width: 80px;
height: 34px;
vertical-align: middle;
padding: 0;
border: 0;
}
.searchBtn:hover {
background-color: #3171f3;
}
.searchBtn:active {
background-color: #2964bb;
}
.searchSpan{
padding-left: 10px;
padding-right: 10px;
margin-top: 0px;
margin-bottom: 0px;
border-color: #b8b8b8;
width: 40%;
vertical-align: middle;
display: inline-block;
height: 34px;
border: 1px solid #b6b6b6;
}
.searchText{
font-size: 16px;
width: 100%;
margin-top: 5px;
outline: 0;
border: 0;
}
dt{
margin: 0px;
padding: 0px;
font-size: 16px;
color: #303030;
line-height: 24px;
margin-top: 20px;
}
dd{
margin: 0px;
padding: 0px;
font-size: 14px;
line-height: 22px;
color: #999999;
}
a{
text-decoration: none;
}
.contentDiv{
width: 800px;
text-align: left;
padding-bottom: 30px;
}
.contentDiv em{
color: #CA0C16;
font-style:normal;
}
.nextdiv{
width: 50px;
height: 50px;
position: relative;
}
.next a:visited {
text-decoration: none;
color: #9B8878;
}
</style>
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.0.js"></script>
<script >
String.prototype.replaceAll = function(s1,s2){
return this.replace(new RegExp(s1,"gm"),s2);
}
$(document).ready(function(){
var width =$(window).width();
if(width<900){
$(".searchSpan").css("width","50%")
$(".searchBtn").css("width","20%")
$("#contentDiv").css("width","80%")
}
else{
$(".searchSpan").css("width","600px")
$("#contentDiv").css("width","800px")
$(".searchBtn").css("width","80px")
$(".searchSpan").css("margin-left","-85px")
}
$('.searchText').bind('keydown',function(event){
if(event.keyCode == "13") {
openSearch(0);
}
});
});
function openSearch(state){
if(state!=null){
$("#contentDiv").html("");
}
isLoad = true;
$.ajax({
type: "GET",
url: "search",
data: {"key":$("#searchText").val(),"page":1},
dataType: "text",
success: function(data){
$("contentDiv").html(data);
}
});
}
</script>
</head>
<body >
<div align="center" style="margin-top: 30px;font-size: 24px;margin-left: -50px;" >博客搜</div>
<div align="center" style="margin-top: 20px;" >
<span class="searchSpan">
<input type="text" id="searchText"
value="spring"
class="searchText" /></span>
<input type="submit" value="Search" id="su" class="searchBtn"
onclick="openSearch(0)"
></input>
</div>
<div align="center">
<div id="contentDiv" class="contentDiv" ></div>
</div>
</body>
</html>
View Code
访问下 好的 一个丑陋的网站就做好了
回到ClientService
我们这边是用 String str= restTemplate.getForObject("http://localhost:8981/search?key={key}&page={page}",String.class,map);
restTemplate直接访问真实地址的 这样比较low, 通过Eureka Server上注册的Application Name我们可以来直接访问Client
修改下ClientService
@Service
public class ClientService {
@Autowired RestTemplate restTemplate;
@Autowired
private EurekaClient discoveryClient;
public String search(String key,String page) {
HashMap<String, String> map = new HashMap<>();
map.put("key", key);
map.put("page", page);
String str= restTemplate.getForObject(serviceUrl return str;
}
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
public String serviceUrl(String serviceId) {
InstanceInfo instance = discoveryClient.getNextServerFromEureka(serviceId, false);
return instance.getHomePageUrl();
}
}
这里需要说明下 用了rabbit 如果直接访问真实地址会找不到 ,默认是通过serviceID解析
继续测试下 没问题
我们把写死在代码里 看着很不舒服 下面就是将服务名通过ConfigServer获取
新建个 工程
application.properties
eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.application.name=config
server.port=8782
spring.cloud.config.server.git.uri=https://github.com/dikeboy/myeureka_config.git
spring.cloud.config.server.git.search-paths=config
我 这里是通过Github仓库获取的 uri是GIT仓库名 paths代表要搜索的路径 ,当然也可以配置在本地
Application
@EnableEurekaClient
@EnableConfigServer
@SpringBootApplication
public class SpringtestConfiApplication {
public static void main(String[] args) {
SpringApplication.run(SpringtestConfiApplication.class, args);
}
}
访问下成功 说明已配置成功
下面回到Client项目 在resource 下新建一个bootstrap.xml或者properties bootstrap.xml优先级高于application.xml
spring.application.name=client
server.port=8881
spring.cloud.config.label=master
spring.cloud.config.profile=dev
spring.cloud.config.uri=http://localhost:8782/
Github上的名字client-dev.properties , client是我们当前服务的名称 dev对应 uri是我们config server的地址
Pom加入
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
修改Client Service
package com.springtest.client;
import java.util.HashMap;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClient;
@Service
public class ClientService {
@Autowired RestTemplate restTemplate;
@Autowired
private EurekaClient discoveryClient;
@Value("${serviceId}")
public String serviceId;
public String search(String key,String page) {
HashMap<String, String> map = new HashMap<>();
map.put("key", key);
map.put("page", page);
String str= restTemplate.getForObject(serviceUrl(serviceId)+"/search?key={key}&page={page}",String.class,map);
return str;
}
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
public String serviceUrl(String serviceId) {
InstanceInfo instance = discoveryClient.getNextServerFromEureka(serviceId, false);
return instance.getHomePageUrl();
}
}
View Code
这里需要注意几点 使用@value注入 一定要保证Config Server正常启动的状态 配置文件不能出错 不然可能启动不了项目
再次访问下地址测试下