行为性模式-模版模式
在抽象父类中定义public类型的方法供外部调用,在public类型方法中引入抽象方法定义执行顺序,抽象方法让各实现类实现
父类抽象类显示定义了有参构造方法,没有显示定义默认无参构造方法,子类继承父类必须要显示调用父类有参构造方法(不管是抽象父类还是非抽象父类,实例化的时候首先调用父类构造方法在调用子类构造方法)
技术点
自定义HttpClient访问http请求
关闭资源 connection(无异常):直接使用断言:assert connect != null
使用正则表达式 正向后查找、正向前查找 搜索内容:
// <html><head><title>这是页面标题</title></head><body>...</body></html>
(?<=title\\>).*(?=</title)
模版模式实现
抽象父类(模板-定义执行顺序)
public abstract class NetMall {
protected Logger logger = LoggerFactory.getLogger(NetMall.class);
private String uId;
private String password;
public NetMall(String uId, String password) {
this.uId = uId;
this.password = password;
}
public String generateGoodsPoster(String skuUrl) {
// 定义执行顺序
// 登录
if (!login(uId, password)) {
return null;
}
// 爬虫
Map<String,String> reptileMap = reptile(skuUrl);
// 生产海报(base64加密)
return createBase64(reptileMap);
}
protected abstract boolean login(String uId,String password);
protected abstract Map<String,String> reptile(String skuUrl);
protected abstract String createBase64(Map<String,String> retileMap);
}
实现类-按模板定义顺序执行
public class JDNetMall extends NetMall {
public JDNetMall(String uId, String password) {
super(uId, password);
}
@Override
public boolean login(String uId, String password) {
if (null == uId || null == password){
return false;
}
logger.info("模拟京东登录用户名:{},密码:{}",uId,password);
return true;
}
@Override
public Map<String, String> reptile(String skuUrl) {
String reslut = HttpClient.doGet(skuUrl);
Map<String,String> reptileMap = new ConcurrentHashMap<>();
Pattern p9 = Pattern.compile("(?<=title\\>).*(?=</title)");
Matcher m9 = p9.matcher(reslut);
if (m9.find()) {
reptileMap.put("name",m9.group());
}
reptileMap.put("price","1213,70");
logger.info("模拟京东商品爬虫解析:商品名:{},商品价钱:{},商品URL:{}",reptileMap.get("name"),reptileMap.get("price"),skuUrl);
return reptileMap;
}
@Override
public String createBase64(Map<String, String> retileMap) {
logger.info("模拟生成京东商品base64");
return Base64.getEncoder().encodeToString(JSON.toJSONString(retileMap).getBytes());
}
}
测试
public class ApiTest {
private Logger logger = LoggerFactory.getLogger(ApiTest.class);
@Test
public void test1() {
// 测试淘宝
NetMall netMall = new TaoBaoNetMall("1001","******");
String reptile = netMall.generateGoodsPoster("https://detail.tmall.com/item.htm");
logger.info("测试结果:{}",reptile);
}
@Test
public void test2() {
// 测试京东
NetMall netMall = new JDNetMall("1001","******");
String reptile = netMall.generateGoodsPoster("https://item.jd.com/100008348542.html");
logger.info("测试结果:{}",reptile);
}
@Test
public void test3() {
// 测试当当
NetMall netMall = new DangDangNetMall("1001","******");
String reptile = netMall.generateGoodsPoster("http://product.dangdang.com/1509704171.html");
logger.info("测试结果:{}",reptile);
}
}
测试结果
17:25:04.046 [main] INFO com.leilei.design.template.NetMall - 模拟淘宝登录用户名:1001,密码:******
17:25:06.687 [main] INFO com.leilei.design.template.NetMall - 模拟淘宝商品爬虫解析:商品名:�������� - ��è-�����̳� Ʒ����Ʒ �����������˻��� �ṩ��Ʊ �̳DZ���-��è-����è������,商品价钱:1213,70,商品URL:https://detail.tmall.com/item.htm
17:25:06.687 [main] INFO com.leilei.design.template.NetMall - 模拟生成淘宝商品base64
17:25:06.798 [main] INFO c.l.design.template.test.ApiTest - 测试结果:eyJwcmljZSI6IjEyMTMsNzAiLCJuYW1lIjoi77+977+977+977+977+977+977+977+9IC0g77+977+9w6gt77+977+977+977+977+9zLPvv70gxrfvv73vv73vv73vv73GtyDvv73vv73vv73vv73vv73vv73vv73vv73vv73vv73vv73Lu++/ve+/ve+/vSDvv73huanvv73vv73GsSDvv73Ms8ex77+977+977+9Le+/ve+/vcOoLe+/ve+/ve+/ve+/vcOo77+977+977+9zbnvv73vv73vv70ifQ==
Process finished with exit code 0