这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
version: "2.2"
services:
namenode:
image: bde2020/hadoop-namenode:1.1.0-hadoop2.7.1-java8
container_name: namenode
volumes:
- ./hadoop/namenode:/hadoop/dfs/name
- ./input_files:/input_files
environment:
- CLUSTER_NAME=test
env_file:
- ./hadoop.env
ports:
- 50070:50070
resourcemanager:
image: bde2020/hadoop-resourcemanager:1.1.0-hadoop2.7.1-java8
container_name: resourcemanager
depends_on:
- namenode
- datanode1
- datanode2
env_file:
- ./hadoop.env
historyserver:
image: bde2020/hadoop-historyserver:1.1.0-hadoop2.7.1-java8
container_name: historyserver
depends_on:
- namenode
- datanode1
- datanode2
volumes:
- ./hadoop/historyserver:/hadoop/yarn/timeline
env_file:
- ./hadoop.env
nodemanager1:
image: bde2020/hadoop-nodemanager:1.1.0-hadoop2.7.1-java8
container_name: nodemanager1
depends_on:
- namenode
- datanode1
- datanode2
env_file:
- ./hadoop.env
datanode1:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
container_name: datanode1
depends_on:
- namenode
volumes:
- ./hadoop/datanode1:/hadoop/dfs/data
env_file:
- ./hadoop.env
datanode2:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
container_name: datanode2
depends_on:
- namenode
volumes:
- ./hadoop/datanode2:/hadoop/dfs/data
env_file:
- ./hadoop.env
datanode3:
image: bde2020/hadoop-datanode:1.1.0-hadoop2.7.1-java8
container_name: datanode3
depends_on:
- namenode
volumes:
- ./hadoop/datanode3:/hadoop/dfs/data
env_file:
- ./hadoop.env
master:
image: gettyimages/spark:2.3.0-hadoop-2.8
container_name: master
command: bin/spark-class org.apache.spark.deploy.master.Master -h master
hostname: master
environment:
MASTER: spark://master:7077
SPARK_CONF_DIR: /conf
SPARK_PUBLIC_DNS: localhost
links:
- namenode
expose:
- 7001
- 7002
- 7003
- 7004
- 7005
- 7077
- 6066
ports:
- 4040:4040
- 6066:6066
- 7077:7077
- 8080:8080
volumes:
- ./conf/master:/conf
- ./data:/tmp/data
- ./jars:/root/jars
worker1:
image: gettyimages/spark:2.3.0-hadoop-2.8
container_name: worker1
command: bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077
hostname: worker1
environment:
SPARK_CONF_DIR: /conf
SPARK_WORKER_CORES: 2
SPARK_WORKER_MEMORY: 2g
SPARK_WORKER_PORT: 8881
SPARK_WORKER_WEBUI_PORT: 8081
SPARK_PUBLIC_DNS: localhost
links:
- master
expose:
- 7012
- 7013
- 7014
- 7015
- 8881
volumes:
- ./conf/worker1:/conf
- ./data/worker1:/tmp/data
worker2:
image: gettyimages/spark:2.3.0-hadoop-2.8
container_name: worker2
command: bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077
hostname: worker2
environment:
SPARK_CONF_DIR: /conf
SPARK_WORKER_CORES: 2
SPARK_WORKER_MEMORY: 2g
SPARK_WORKER_PORT: 8881
SPARK_WORKER_WEBUI_PORT: 8081
SPARK_PUBLIC_DNS: localhost
links:
- master
expose:
- 7012
- 7013
- 7014
- 7015
- 8881
volumes:
- ./conf/worker2:/conf
- ./data/worker2:/tmp/data
worker3:
image: gettyimages/spark:2.3.0-hadoop-2.8
container_name: worker3
command: bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077
hostname: worker3
environment:
SPARK_CONF_DIR: /conf
SPARK_WORKER_CORES: 2
SPARK_WORKER_MEMORY: 2g
SPARK_WORKER_PORT: 8881
SPARK_WORKER_WEBUI_PORT: 8081
SPARK_PUBLIC_DNS: localhost
links:
- master
expose:
- 7012
- 7013
- 7014
- 7015
- 8881
volumes:
- ./conf/worker3:/conf
- ./data/worker3:/tmp/data
worker4:
image: gettyimages/spark:2.3.0-hadoop-2.8
container_name: worker4
command: bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077
hostname: worker4
environment:
SPARK_CONF_DIR: /conf
SPARK_WORKER_CORES: 2
SPARK_WORKER_MEMORY: 2g
SPARK_WORKER_PORT: 8881
SPARK_WORKER_WEBUI_PORT: 8081
SPARK_PUBLIC_DNS: localhost
links:
- master
expose:
- 7012
- 7013
- 7014
- 7015
- 8881
volumes:
- ./conf/worker4:/conf
- ./data/worker4:/tmp/data
worker5:
image: gettyimages/spark:2.3.0-hadoop-2.8
container_name: worker5
command: bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077
hostname: worker5
environment:
SPARK_CONF_DIR: /conf
SPARK_WORKER_CORES: 2
SPARK_WORKER_MEMORY: 2g
SPARK_WORKER_PORT: 8881
SPARK_WORKER_WEBUI_PORT: 8081
SPARK_PUBLIC_DNS: localhost
links:
- master
expose:
- 7012
- 7013
- 7014
- 7015
- 8881
volumes:
- ./conf/worker5:/conf
- ./data/worker5:/tmp/data
worker6:
image: gettyimages/spark:2.3.0-hadoop-2.8
container_name: worker6
command: bin/spark-class org.apache.spark.deploy.worker.Worker spark://master:7077
hostname: worker6
environment:
SPARK_CONF_DIR: /conf
SPARK_WORKER_CORES: 2
SPARK_WORKER_MEMORY: 2g
SPARK_WORKER_PORT: 8881
SPARK_WORKER_WEBUI_PORT: 8081
SPARK_PUBLIC_DNS: localhost
links:
- master
expose:
- 7012
- 7013
- 7014
- 7015
- 8881
volumes:
- ./conf/worker6:/conf
- ./data/worker6:/tmp/data
aa.b User_talk:Sevela.p 1 5786
这一行由空格字符分割成了四个字段:
| 内容 | 意义 |
|---|---|
| aa.b | 项目名称,".b"表示wikibooks |
| User_talk:Sevela.p | 网页的三级目录 |
| 1 | 一小时内的访问次数 |
| 5786 | 一小时内被请求的字节总数 |

| 名称 | 链接 | 备注 |
|---|---|---|
| 项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
| git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
| git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.bolingcavalry</groupId>
<artifactId>sparkdemo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-core_2.11</artifactId>
<version>2.3.2</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<testSourceDirectory>src/test/java</testSourceDirectory>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<archive>
<manifest>
<mainClass></mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<includeProjectDependencies>false</includeProjectDependencies>
<includePluginDependencies>false</includePluginDependencies>
<classpathScope>compile</classpathScope>
<mainClass>com.bolingcavalry.sparkdemo.app.WikiRank</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
package com.bolingcavalry.sparkdemo.bean;
import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;
/**
* @Description: 数据结构类
* @author: willzhao E-mail: zq2599@gmail.com
* @date: 2019/2/10 15:33
*/
public class PageInfo implements Serializable {
/**
* 还原的url地址
*/
private String url;
/**
* urldecode之后的三级域名
*/
private String name;
/**
* 该三级域名的请求次数
*/
private int requestTimes;
/**
* 该地址被请求的字节总数
*/
private long requestLength;
/**
* 对应的原始字段
*/
private List<String> raws = new LinkedList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getRequestTimes() {
return requestTimes;
}
public void setRequestTimes(int requestTimes) {
this.requestTimes = requestTimes;
}
public long getRequestLength() {
return requestLength;
}
public void setRequestLength(long requestLength) {
this.requestLength = requestLength;
}
public List<String> getRaws() {
return raws;
}
public void setRaws(List<String> raws) {
this.raws = raws;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
package com.bolingcavalry.sparkdemo.util;
import org.apache.commons.lang3.StringUtils;
/**
* @Description: 常用的静态工具放置在此
* @author: willzhao E-mail: zq2599@gmail.com
* @date: 2019/2/16 9:01
*/
public class Tools {
/**
* 域名的格式化模板
*/
private static final String URL_TEMPALTE = "https://%s/wiki/%s";
/**
* 根据项目名称和三级域名还原完整url,
* 还原逻辑来自:https://wikitech.wikimedia.org/wiki/Analytics/Archive/Data/Pagecounts-raw
* @param project
* @param thirdLvPath
* @return
*/
public static String getUrl(String project, String thirdLvPath){
//如果入参不合法,就返回固定格式的错误提示
if(StringUtils.isBlank(project) || StringUtils.isBlank(thirdLvPath)){
return "1. invalid param (" + project + ")(" + thirdLvPath + ")";
}
//检查project中是否有"."
int dotOffset = project.indexOf('.');
//如果没有".",就用project+".wikipedia.org"作为一级域名
if(dotOffset<0){
return String.format(URL_TEMPALTE,
project + ".wikipedia.org",
thirdLvPath);
}
//如果有".",就用"."之后的字符串按照不同的逻辑转换
String code = project.substring(dotOffset);
//".mw"属于移动端网页,统计的逻辑略微复杂,详情参考网页链接,这里不作处理直接返回固定信息
if(".mw".equals(code)){
return "mw page (" + project + ")(" + thirdLvPath + ")";
}
String firstLvPath = null;
//就用"."之后的字符串按照不同的逻辑转换
switch(code){
case ".b":
firstLvPath = ".wikibooks.org";
break;
case ".d":
firstLvPath = ".wiktionary.org";
break;
case ".f":
firstLvPath = ".wikimediafoundation.org";
break;
case ".m":
firstLvPath = ".wikimedia.org";
break;
case ".n":
firstLvPath = ".wikinews.org";
break;
case ".q":
firstLvPath = ".wikiquote.org";
break;
case ".s":
firstLvPath = ".wikisource.org";
break;
case ".v":
firstLvPath = ".wikiversity.org";
break;
case ".voy":
firstLvPath = ".wikivoyage.org";
break;
case ".w":
firstLvPath = ".mediawiki.org";
break;
case ".wd":
firstLvPath = ".wikidata.org";
break;
}
if(null==firstLvPath){
return "2. invalid param (" + project + ")(" + thirdLvPath + ")";
}
//还原地址
return String.format(URL_TEMPALTE,
project.substring(0, dotOffset) + firstLvPath,
thirdLvPath);
}
public static void main(String[] args){
String str = "abc.123456";
System.out.println(str.substring(str.indexOf('.')));
}
}
package com.bolingcavalry.sparkdemo.app;
import com.bolingcavalry.sparkdemo.bean.PageInfo;
import com.bolingcavalry.sparkdemo.util.Tools;
import org.apache.commons.lang3.StringUtils;
import org.apache.spark.SparkConf;
import org.apache.spark.api.java.JavaPairRDD;
import org.apache.spark.api.java.JavaRDD;
import org.apache.spark.api.java.JavaSparkContext;
import org.apache.spark.api.java.function.Function;
import org.apache.spark.api.java.function.Function2;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.Tuple2;
import java.net.URLDecoder;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* @Description: 根据wiki的统计来查找最高访问量的文章
* @author: willzhao E-mail: zq2599@gmail.com
* @date: 2019/2/8 17:21
*/
public class WikiRank {
private static final Logger logger = LoggerFactory.getLogger(WikiRank.class);
private static final int TOP = 100;
public static void main(String[] args) {
if(null==args
|| args.length<2
|| StringUtils.isEmpty(args[0])
|| StringUtils.isEmpty(args[1])) {
logger.error("invalid params!");
}
String hdfsHost = args[0];
String hdfsPort = args[1];
SparkConf sparkConf = new SparkConf().setAppName("Spark WordCount Application (java)");
JavaSparkContext javaSparkContext = new JavaSparkContext(sparkConf);
String hdfsBasePath = "hdfs://" + hdfsHost + ":" + hdfsPort;
//文本文件的hdfs路径
String inputPath = hdfsBasePath + "/input/*";
//输出结果文件的hdfs路径
String outputPath = hdfsBasePath + "/output/"
+ new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
logger.info("input path : {}", inputPath);
logger.info("output path : {}", outputPath);
logger.info("import text");
//导入文件
JavaRDD<String> textFile = javaSparkContext.textFile(inputPath);
logger.info("do map operation");
JavaPairRDD<String, PageInfo> counts = textFile
//过滤掉无效的数据
.filter((Function<String, Boolean>) v1 -> {
if(StringUtils.isBlank(v1)){
return false;
}
//分割为数组
String[] array = v1.split(" ");
/**
* 以下情况都要过滤掉
* 1. 名称无效(array[1])
* 2. 请求次数无效(array[2)
* 3. 请求总字节数无效(array[3)
*/
if(null==array
|| array.length<4
|| StringUtils.isBlank(array[1])
|| !StringUtils.isNumeric(array[2])
|| !StringUtils.isNumeric(array[3])){
logger.error("find invalid data [{}]", v1);
return false;
}
return true;
})
//将每一行转成一个PageInfo对象
.map((Function<String, PageInfo>) v1 -> {
String[] array = v1.split(" ");
PageInfo pageInfo = new PageInfo();
try {
pageInfo.setName(URLDecoder.decode(array[1], "UTF-8"));
}catch (Exception e){
//有的字符串没有做过urlencode,此时做urldecode可能抛出异常(例如abc%),此时用原来的内容作为name即可
pageInfo.setName(array[1]);
}
pageInfo.setUrl(Tools.getUrl(array[0], array[1]));
pageInfo.setRequestTimes(Integer.valueOf(array[2]));
pageInfo.setRequestLength(Long.valueOf(array[3]));
pageInfo.getRaws().add(v1);
return pageInfo;
})
//转成键值对,键是url,值是PageInfo对象
.mapToPair(pageInfo -> new Tuple2<>(pageInfo.getUrl(), pageInfo))
//按照url做reduce,将请求次数累加
.reduceByKey((Function2<PageInfo, PageInfo, PageInfo>) (v1, v2) -> {
v2.setRequestTimes(v2.getRequestTimes() + v1.getRequestTimes());
v2.getRaws().addAll(v1.getRaws());
return v2;
});
logger.info("do convert");
//先将key和value倒过来,再按照key排序
JavaPairRDD<Integer, PageInfo> sorts = counts
//key和value颠倒,生成新的map
.mapToPair(tuple2 -> new Tuple2<>(tuple2._2().getRequestTimes(), tuple2._2()))
//按照key倒排序
.sortByKey(false);
logger.info("take top " + TOP);
//取前10个
List<Tuple2<Integer, PageInfo>> top = sorts.take(TOP);
StringBuilder sbud = new StringBuilder("top "+ top + " word :\n");
//打印出来
for(Tuple2<Integer, PageInfo> tuple2 : top){
sbud.append(tuple2._2().getName())
.append("\t")
.append(tuple2._1())
.append("\n");
}
logger.info(sbud.toString());
logger.info("merge and save as file");
//分区合并成一个,再导出为一个txt保存在hdfs
javaSparkContext
.parallelize(top)
.coalesce(1)
.map(
tuple2 -> new Tuple2<>(tuple2._2().getRequestTimes(), tuple2._2().getName() + " ### " + tuple2._2().getUrl() +" ### " + tuple2._2().getRaws().toString())
)
.saveAsTextFile(outputPath);
logger.info("close context");
//关闭context
javaSparkContext.close();
}
}
mvn clean package -Dmaven.test.skip=true
docker exec namenode hdfs dfs -put /input_files/input /
docker exec -it master spark-submit \
--class com.bolingcavalry.sparkdemo.app.WikiRank \
--executor-memory 1g \
--total-executor-cores 12 \
/root/jars/sparkdemo-1.0-SNAPSHOT.jar \
namenode \
8020
en 111840450
Main_Page 61148163
ja 20336203
es 18133852
Заглавная_страница 16997475
de 12537288
ru 10127971
fr 9296777
it 9011481
pt 5904807
id 3472100
tr 3089611
pl 3051718
ar 3023412
nl 2372696
zh 1987233
sv 1845525
fa 1687804
ko 1511408
commons 1138613
fi 1123291
th 1012375
vi 1007987
he 822433
Wikipedia:Hauptseite 767106
cs 750085
hu 687040
Wikipédia:Accueil_principal 597885
da 512714
no 507885
Special:Search 493995
ro 488945
uk 419609
Special:NewItem 414436
hi 399883
Antoninus_Pius 345542
el 342715
Hoofdpagina 287517
tl 274145
bg 252691
Wikipedia:Portada 250932
Liste_des_automobiles_Ferrari 237985
hr 228896
メインページ 227591
Начална_страница 220605
Okto 211002
Proyecto_40 207534
root@willzhao-deepin:~# docker exec namenode hdfs dfs -ls /output/
Found 3 items
drwxr-xr-x - root supergroup 0 2019-02-16 00:53 /output/20190216005136
drwxr-xr-x - root supergroup 0 2019-02-16 01:50 /output/20190216014759
drwxr-xr-x - root supergroup 0 2019-02-16 02:41 /output/20190216021144
root@willzhao-deepin:~# docker exec namenode hdfs dfs -ls /output/20190216021144
Found 2 items
-rw-r--r-- 3 root supergroup 0 2019-02-16 02:41 /output/20190216021144/_SUCCESS
-rw-r--r-- 3 root supergroup 105181 2019-02-16 02:41 /output/20190216021144/part-00000
(63364,2016_Summer_Olympics ### https://en.wikipedia.org/wiki/2016_Summer_Olympics ### [en 2016_Summer_Olympics 3396 274589952, en 2016_Summer_Olympics 3015 252640325, en 2016_Summer_Olympics 3136 260875102, en 2016_Summer_Olympics 3094 257683527, en 2016_Summer_Olympics 2302 189633601, en 2016_Summer_Olympics 2532 211137547, en 2016_Summer_Olympics 2073 174153850, en 2016_Summer_Olympics 2425 201808231, en 2016_Summer_Olympics 2869 244961273, en 2016_Summer_Olympics 2647 227408637, en 2016_Summer_Olympics 3173 276779678, en 2016_Summer_Olympics 3242 261206575, en 2016_Summer_Olympics 1871 168316209, en 2016_Summer_Olympics 2234 204588727, en 2016_Summer_Olympics 2857 239335148, en 2016_Summer_Olympics 2345 197360752, en 2016_Summer_Olympics 2949 248777317, en 2016_Summer_Olympics 2040 171690687, en 2016_Summer_Olympics 4006 332402716, en 2016_Summer_Olympics 3137 274672915, en 2016_Summer_Olympics 1895 156985346, en 2016_Summer_Olympics 2089 180840058, en 2016_Summer_Olympics 2062 177089806, en 2016_Summer_Olympics 1975 169774986])
(62904,index.html ### https://de.wikipedia.org/wiki/index.html ### [de index.html 1325 16171364, de index.html 2680 30968912, de index.html 2458 27982474, de index.html 2703 30869488, de index.html 2829 32784835, de index.html 2674 30702050, de index.html 2346 26947956, de index.html 2573 29374195, de index.html 2610 30237824, de index.html 2689 32111034, de index.html 2748 31632152, de index.html 2659 30566670, de index.html 2657 30411903, de index.html 2765 32298328, de index.html 2982 34626678, de index.html 2953 33925805, de index.html 2543 29180781, de index.html 2722 31230645, de index.html 2810 32517269, de index.html 2307 26760806, de index.html 2847 33270784, de index.html 2776 32310052, de index.html 2544 29206518, de index.html 2704 31382398])
学习路上,你不孤单,欣宸原创一路相伴...
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳
在Ruby中可以使用哪些替代方法来ping一个ip地址?标准库“ping”库的功能似乎非常有限。我对在这里滚动我自己的代码不感兴趣。有没有好的gem?我应该接受它并忍受它吗?(我在Linux上使用Ruby1.8.6编写代码) 最佳答案 net-ping值得一看。它允许TCPping(如标准rubyping),但也允许UDP、HTTP和ICMPping。ICMPping需要root权限,但其他则不需要。 关于ruby-Pingruby网站?,我们在StackOverflow上找到一个类
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
我正在尝试使用Curbgem执行以下POST以解析云curl-XPOST\-H"X-Parse-Application-Id:PARSE_APP_ID"\-H"X-Parse-REST-API-Key:PARSE_API_KEY"\-H"Content-Type:image/jpeg"\--data-binary'@myPicture.jpg'\https://api.parse.com/1/files/pic.jpg用这个:curl=Curl::Easy.new("https://api.parse.com/1/files/lion.jpg")curl.multipart_form_
无论您是想搭建桌面端、WEB端或者移动端APP应用,HOOPSPlatform组件都可以为您提供弹性的3D集成架构,同时,由工业领域3D技术专家组成的HOOPS技术团队也能为您提供技术支持服务。如果您的客户期望有一种在多个平台(桌面/WEB/APP,而且某些客户端是“瘦”客户端)快速、方便地将数据接入到3D应用系统的解决方案,并且当访问数据时,在各个平台上的性能和用户体验保持一致,HOOPSPlatform将帮助您完成。利用HOOPSPlatform,您可以开发在任何环境下的3D基础应用架构。HOOPSPlatform可以帮您打造3D创新型产品,HOOPSSDK包含的技术有:快速且准确的CAD
本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01 客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02 数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit