专栏名称: 沪江技术学院
开发
目录
相关文章推荐
媒哥媒体招聘  ·  抖音招聘! ·  2 天前  
草叔消费升级研究  ·  【东吴商社】全球消费企业二代接班深度复盘—— ... ·  2 天前  
传媒招聘那些事儿  ·  网易:高级/资深新媒体品牌策划专员 ·  1 周前  
视觉志  ·  七言 | 现在的你,快乐吗? ·  1 周前  
51好读  ›  专栏  ›  沪江技术学院

部署 LanguageTool 到 Servlet

沪江技术学院  · 掘金  ·  · 2017-12-15 03:27

正文

文:何晓杰

本文原创,转载请注明作者及出处

利用 LanguageTool 来实现语法或拼写的检查是一件很方便的事情,以下内容展示了如何部署一个 LanguageTool 的 Servlet。

首先 clone 代码:

  1. git clone [email protected]:languagetool-org/languagetool.git

由于项目很大,clone 需要比较久,完成后我们可以编译它:

  1. $ mvn clean test

  2. $ ./build.sh languagetool-standalone package -DskipTests

取决于网速,编译可能会花 5~30 分钟,编译完成后,可以在 languagetool-standalone/target/LanguageTool-4.0-SNAPSHOT 目录下找到编译结果。

编译结果包含了 languagetool.jarlanguagetool-server.jarlanguagetool-commandline.jar 这三个文件,以及一大堆其他的东西。

此时即可用以下命令来进行测试,如果编译结果正确,那么可以直接运行起一个带窗口的校验工具,也可以运行一个命令行的工具:

  1. $ echo "I was do book a tickt last night" | java -jar languagetool-commandline.jar -l en-US -m en --json -

上面的句子有语法和拼写的错误,不要在意,是故意写错供查的,这个代码将会返回检查结果:

  1. {

  2.    "software": {

  3.        "name": "LanguageTool",

  4.        "version": "4.0-SNAPSHOT",

  5.        "buildDate": "2017-11-15 13:25",

  6.        "apiVersion": 1,

  7.        "status": ""

  8.    },

  9.    "warnings": {

  10.        "incompleteResults": false

  11.    },

  12.    "language": {

  13.        "name": "English (US)",

  14.        "code": "en-US"

  15.    },

  16.    "matches": [

  17.        {

  18.            "message": "Consider using a past participle here: \"done\".",

  19.            "shortMessage": "Possible agreement error",

  20.            "replacements": [

  21.                {

  22.                    "value": "done"

  23.                }

  24.            ],

  25.            "offset": 6,

  26.            "length": 2,

  27.            "context": {

  28.                "text": "I was do book a tickt last night ",

  29.                "offset": 6,

  30.                "length": 2

  31.            },

  32.            "rule": {

  33.                "id": "BEEN_PART_AGREEMENT",

  34.                "subId": "1",

  35.                "description": "Agreement: 'been' or 'was' + past tense",

  36.                "issueType": "grammar",

  37.                "category": {

  38.                    "id": "GRAMMAR",

  39.                    "name": "Grammar"

  40.                }

  41.            }

  42.        },

  43.        {

  44.            "message": "Possible spelling mistake found",

  45.            "shortMessage": "Spelling mistake",

  46.            "replacements": [

  47.                {

  48.                    "value": "ticket"

  49.                },

  50.                {

  51.                    "value": "tick"

  52.                },

  53.                {

  54.                    "value": "ticks"

  55.                },

  56.                {

  57.                    "value": "tic kt"

  58.                },

  59.                {

  60.                    "value": "tick t"

  61.                }

  62.            ],

  63.            "offset": 16,

  64.            "length": 5,

  65.            "context": {

  66.                "text": "I was do book a tickt last night ",

  67.                "offset": 16,

  68.                "length": 5

  69.            },

  70.            "rule": {

  71.                "id": "MORFOLOGIK_RULE_EN_US",

  72.                "description": "Possible spelling mistake",

  73.                "issueType": "misspelling",

  74.                "category": {

  75.                    "id": "TYPOS",

  76.                    "name": "Possible Typo"

  77.                }

  78.            }

  79.        }

  80.    ]

  81. }

这样先证明了编译结果的正确与可用。接下去就要写一个简单的 Servlet,把 LanguageTool 封装进去使用,关于 Servlet 的开发就不再赘述了。

建立 Servlet 项目后,将所有 lib 下的文件,连同三个主要 jar 包一起复制到 WEB-INF/lib 内,然后在 Servlet 文件内编写以下代码:

  1. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

  2.    JLanguageTool lt = new JLanguageTool(Languages.getLanguageForShortCode("en-US"));

  3.    List<RuleMatch> list = lt.check(request.getParameter("text"));

  4.    String s = "";

  5.    for (RuleMatch rm: list) {

  6.        s += String.format("message => %s, from => %d, to => %d<br>", rm.getMessage(), rm.getFromPos(), rm.getToPos());

  7.    }

  8.    response.setContentType("text/plain");

  9.    PrintWriter pw = response.getWriter();

  10.    pw.write(s);

  11. }

看起来很简单,编译通过,但是实际运行的时候,会报一个奇怪的错误:

  1. 'en-US' is not a language code known to LanguageTool. Supported language codes are: xx-XX. The list of languages is read from META-INF/org/languagetool/language-module.properties in the Java classpath.

看起来似乎是少复制了 META-INF 里的内容,但是实际上将编译目录内的 META-INF 拷到 Servlet 项目内的任何目录都不行。

经过一番对编译结果的审视,发现编译后的语言全部以 class 的方式,保存在 org/languagetool/language 内,同时还附带大量的 properties 文件。

这样一看,就找到解决问题的方法了,无非就是要多做一个 jar,而原本的编译脚本并不会为我们制作这样一个 jar 包。

  1. $ zip -r languages.jar META-INF/ org/

这样就得到一个 languages.jar,把它拷到 WEB-INF/lib 内,就可以在 Servlet 内直接引用了,以上错误也得到了解决。同时,我们还可以把代码写得更简单:

  1. JLanguageTool lt = new JLanguageTool(new AmericanEnglish());

最后,可以用 curl 来进行测试,证明我们的服务器的确已经正常工作了:

  1. $ curl -d "text=I was do book a tickt last night" "http://localhost:8080/demo"

  2. message => Consider using a past participle here: <suggestion>done</suggestion>., from => 6, to => 8<br>message => Possible spelling mistake found, from => 16, to => 21

技术沙龙推荐

点击下方图片即可阅读

翻译 | 调整JavaScript抽象的迭代方案

翻译 | 产品经理的谈判秘笈

后端服务性能压测实践

从错误码406说起