Spring cloud实战 从零开始一个简单搜索网站(二)

先来说下我的网站架构吧  

前面大家也看到了  既然叫博客搜  自然是搜索 博客的   我把每个网站会抽象成一个Client (为了更好的学习cloud) 

上面只是展示了主要部分  像Hystrix Ribbon  Zuul等等就不画上去了

下面我们再建一个Client  选Eureka Server就可以了

修改下Application

@EnableEurekaClient
@SpringBootApplication
public class SpringtestCsdnApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringtestCsdnApplication.class, args);
    }
}

修改下Application.properties

eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
spring.application.name=csdn
server.port=8981

新建一个Controller

@RestController
public class CsdnController {
      @RequestMapping(value ="/search")
        public String search(@RequestParam("key") String key,@RequestParam("page") String page) {
              return "hello";
          }
}

测试下 

下面是爬取CSDN搜索的接口 ,比较简单  没做什么处理

这里我们引入了 谷歌的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://so.csdn.net/so/search/wap.do?callback=&q=");
        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 CsdnController {
    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

重新测试下接口

数据已经有了  

我们的CSDN端是不直接访问的 , 需要通过Client来访问  下面可以结合下前面做的搜索框了

回到Client项目   我们先新建一个service 用来处理 连接 CSDN 

@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("CSDN")+"/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();
    }
}

这里需要说明下 用了rabbit  如果直接访问真实地址会找不到 ,默认是通过serviceID解析 

 

继续测试下 没问题

我们把CSDN 写死在代码里  看着很不舒服  下面就是将服务名通过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正常启动的状态  配置文件不能出错  不然可能启动不了项目

再次访问下地址测试下

猜你喜欢

转载自www.cnblogs.com/dikeboy/p/10052921.html