SpringMVC+Maven开发最小“自然语言理解”项目攻略(附源码打包下载及详细说明)
来源:互联网 发布:克里斯 洛克 知乎 编辑:程序博客网 时间:2024/06/06 08:37
[置顶] SpringMVC+Maven开发最小“自然语言理解”项目攻略(附源码打包下载及详细说明)
Spring MVC概述
Spring MVC框架是一个开源的Java平台,为开发强大的基于Java的Web应用程序提供全面的基础架构支持非常容易和非常快速。
Spring web MVC框架提供了MVC(模型 - 视图 - 控制器)架构和用于开发灵活和松散耦合的Web应用程序的组件。
MVC模式导致应用程序的不同方面(输入逻辑,业务逻辑和UI逻辑)分离,同时提供这些元素之间的松散耦合。
模型(Model)封装了应用程序数据,通常它们将由POJO类组成。
视图(View)负责渲染模型数据,一般来说它生成客户端浏览器可以解释HTML输出。
控制器(Controller)负责处理用户请求并构建适当的模型,并将其传递给视图进行渲染。
项目源码详细介绍
该项目实现了智能解析用户输入语句的语义,输出结果以JSON格式展示。
源码下载:SpringMVCDemoNLI
1、 创建目录结构
创建一个Maven工程为:SpringMVCDemoNLI。下图为最终的目录结构:
2、 配置pom.xml
<?xml version="1.0"?><project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.demo</groupId> <artifactId>SpringMVCDemoNLI</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <name>SpringMVCDemoNLI Maven Webapp</name> <url>http://maven.apache.org</url> <properties> <springframework.version>4.0.6.RELEASE</springframework.version> <hibernate.validator.version>5.1.2.Final</hibernate.validator.version> <javax.validation.version>1.1.0.Final</javax.validation.version> <!-- 主要依赖库的版本定义 --> <httpclient.version>4.5.3</httpclient.version> <commons-lang3.version>3.5</commons-lang3.version> <commons-codec.version>1.10</commons-codec.version> <commons-logging.version>1.2</commons-logging.version> <httpcore.version>4.4.6</httpcore.version> <taglibs-standard.version>1.2.5</taglibs-standard.version> <fastjson.version>1.2.34</fastjson.version> </properties> <dependencies> <!-- Spring dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springframework.version}</version> </dependency> <!-- httpclient --> <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <version>${commons-codec.version}</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>${commons-lang3.version}</version> </dependency> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>${commons-logging.version}</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpcore</artifactId> <version>${httpcore.version}</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>${httpclient.version}</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>${httpclient.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <!-- jsr303 validation dependencies --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>${javax.validation.version}</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>${hibernate.validator.version}</version> </dependency> <!-- Servlet dependencies --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> </dependencies> <build> <defaultGoal>compile</defaultGoal> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.7</source> <target>1.7</target> </configuration> </plugin> </plugins> </pluginManagement> <finalName>SpringMVCDemoNLI</finalName> </build></project>
3、创建POJO/域对象
保存用户提交的数据,并使用验证注释验证属性。
package com.demo.model;import java.io.Serializable;import javax.validation.constraints.Size;public class CorpusInfo implements Serializable { /** * */ private static final long serialVersionUID = 1L; @Size(min=2, max=30) private String corpus; public String getCorpus() { return corpus; } public void setCorpus(String corpus) { this.corpus = corpus; } @Override public String toString() { return ""; }}
4、添加控制器
控制器处理GET和POST请求。
@Controller表明这个类是一个控制器在处理具有模式映射的@RequestMapping请求。这里使用 ‘/’, 它被作为默认的控制器。
方法inputCorpus注解为RequestMethod.GET服务默认是GET请求,并呈现包含空白表单的网页。
方法nliProcess注解为RequestMethod.POST服务处理表单提交POST请求。
@Valid要求spring来验证相关的对象(CorpusInfo)。
package com.demo.controller;import javax.validation.Valid;import org.springframework.stereotype.Controller;import org.springframework.ui.ModelMap;import org.springframework.validation.BindingResult;import org.springframework.web.bind.annotation.ModelAttribute;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestMethod;import com.demo.model.CorpusInfo;import com.demo.util.NLIProcess;@Controller@RequestMapping("/")public class DemoController { private NLIProcess nli = new NLIProcess(); @RequestMapping(method = RequestMethod.GET) public String inputCorpus(ModelMap model) { CorpusInfo cinfo = new CorpusInfo(); model.addAttribute("cinfo", cinfo); return "enroll"; } @RequestMapping(method=RequestMethod.POST) public String nliProcess(@Valid @ModelAttribute("cinfo") CorpusInfo cinfo, BindingResult result, ModelMap model) { if (result.hasErrors()) { return "enroll"; } model.addAttribute("answer", nli.getAnswer(cinfo.getCorpus())); return "success"; }}
nli.getAnswer(cinfo.getCorpus())实现语义解析,这里是使用的欧拉蜜开放平台智能语义解析。
package com.demo.util;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.Calendar;import java.util.List;import org.apache.http.HttpEntity;import org.apache.http.NameValuePair;import org.apache.http.client.entity.UrlEncodedFormEntity;import org.apache.http.client.methods.CloseableHttpResponse;import org.apache.http.client.methods.HttpPost;import org.apache.http.impl.client.CloseableHttpClient;import org.apache.http.impl.client.HttpClients;import org.apache.http.message.BasicNameValuePair;import org.apache.http.util.EntityUtils;import com.alibaba.fastjson.JSONException;import com.alibaba.fastjson.JSONObject;public class NLIProcess { private static final String url = "https://cn.olami.ai/cloudservice/api"; private static final String Appkey = "fcf20941682b494e9db8c23c14deeb74"; private static final String Appsecret = "1bcbbe1fb5924185a13c9b5f6d548ee0"; private static final String api = "nli"; private JSONObject process (String input) { JSONObject NLIresult = new JSONObject(); List<NameValuePair> params = new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("appkey", Appkey)); params.add(new BasicNameValuePair("api", api)); long timestamp = Calendar.getInstance().getTimeInMillis(); params.add(new BasicNameValuePair("timestamp", String.valueOf(timestamp))); params.add(new BasicNameValuePair("sign", generateSign(timestamp))); JSONObject request = new JSONObject(); JSONObject data = new JSONObject(); try { data.put("input_type", 0); data.put("text", input); request.put("data_type", "stt"); request.put("data", data); } catch (JSONException e1) { e1.printStackTrace(); return NLIresult; } params.add(new BasicNameValuePair("rq", request.toString())); params.add(new BasicNameValuePair("cusid", "asdfghj")); CloseableHttpClient httpclient = HttpClients.createDefault(); HttpPost httppost = new HttpPost(url); try { httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8")); CloseableHttpResponse response = httpclient.execute(httppost); try { HttpEntity entity = response.getEntity(); if (entity != null) { String contnt = EntityUtils.toString(entity); NLIresult = JSONObject.parseObject(contnt); } } finally { response.close(); } } catch (Exception e) { e.printStackTrace(); return NLIresult; } finally { try { httpclient.close(); } catch (Exception e) { e.printStackTrace(); } } return NLIresult; } private String generateSign(long timestamp) { String sign = Appsecret + "api=" + api + "appkey=" + Appkey + "timestamp=" + timestamp + Appsecret; return MD5String(sign); } public String MD5String(String str) { try { MessageDigest msgDigest = MessageDigest.getInstance("MD5"); msgDigest.reset(); msgDigest.update(str.getBytes("UTF-8")); byte[] byteArrary = msgDigest.digest(); StringBuffer md5StrBuff = new StringBuffer(); for (int i = 0; i < byteArrary.length; i++) { String tmp = Integer.toHexString(0xFF & byteArrary[i]); if (tmp.length() == 1) { md5StrBuff.append(0).append(tmp); } else { md5StrBuff.append(tmp); } } return md5StrBuff.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); return null; } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } public String getAnswer(String corpus){ if(corpus != null && !corpus.equals("")){ JSONObject jsObj = process(corpus); return formatJson(jsObj); } return "请输入正确的语料!"; } private static String appendJson(String str, int count) { String retStr = "<br>"; for (int i = 0; i < count; i++) { retStr += str; } return retStr; } /** * 将json转成便于阅读的格式 * @param oldJson * @return */ public static String formatJson(JSONObject old) { int i = 0; String space = " "; String formatJson = ""; int indentCount = 0; Boolean isStr = false; String currChar = ""; String oldJson = old.toString(); for (i = 0; i < oldJson.length(); i++) { currChar = oldJson.substring(i, i + 1); switch (currChar) { case "{": case "[": if (!isStr) { indentCount++; formatJson += currChar + appendJson(space, indentCount); } else { formatJson += currChar; } break; case "}": case "]": if (!isStr) { indentCount--; formatJson += appendJson(space, indentCount) + currChar; } else { formatJson += currChar; } break; case ",": if (!isStr) { formatJson += "," + appendJson(space, indentCount); } else { formatJson += currChar; } break; case ":": if (!isStr) { formatJson += ": "; } else { formatJson += currChar; } break; case " ": case "\n": case "\t": if (isStr) { formatJson += currChar; } break; case "\"": if (i > 0 && !oldJson.substring(i - 1, i).equals("\\")) { isStr = !isStr; } formatJson += currChar; break; default: formatJson += currChar; break; } } return formatJson; }}
5、添加配置类
@Configuration指示该类包含注解为@Bean生产Bean管理是由Spring容器的一个或多个 bean 的方法。
@EnableWebMvc 等效于 mvc:annotation-driven 在XML文件中。
@ComponentScan 等效于 context:component-scan base-package=”…” 提供具有到哪里查找管理Spring beans/类。
方法ViewResolver 配置一个 ViewResolver 用来找出真正的视图。
方法 addResourceHandlers 配置 ResourceHandler 静态资源。例子中,将css文件放在 Web应用程序的 /static/css 目录中。
package com.demo.configuration;import org.springframework.context.MessageSource;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.ComponentScan;import org.springframework.context.annotation.Configuration;import org.springframework.context.support.ResourceBundleMessageSource;import org.springframework.web.servlet.ViewResolver;import org.springframework.web.servlet.config.annotation.EnableWebMvc;import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.servlet.view.InternalResourceViewResolver;import org.springframework.web.servlet.view.JstlView;@Configuration@EnableWebMvc@ComponentScan(basePackages = "com.demo")public class DemoConfiguration extends WebMvcConfigurerAdapter { @Bean public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setViewClass(JstlView.class); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource; } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**").addResourceLocations("/static/"); }}
方法messageSource 配置消息包,以支持[国际化]消息属性文件。Spring 将搜索应用程序类路径中一个名为messages.properties文件:
Size.cinfo.corpus=corpus must be between {2} and {1} characters long
6、添加视图(JSP页面)
添加两个JSP页面。第一个将包含一个表单,从用户接收输入,第二个是当表单输入验证成功时会显示成功消息给用户。
WEB-INF/views/enroll.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><html><head><meta http-equiv="Content-Type" content="text/html; charset=Utf-8"><title>智能语义解析——基于欧拉蜜开放平台</title><link href="<c:url value='/static/css/custom.css' />" rel="stylesheet"></link></head><body> <div class="form-container"> <h1>智能语义理解</h1> <form:form method="POST" modelAttribute="cinfo" class="form-horizontal"> <div class="row"> <label class="form-group col-md-1" for="corpus">输入语句:</label> <div class="form-group col-md-2"> <form:input type="text" path="corpus" id="corpus" class="form-control input-sm" /> <div class="has-error"> <form:errors path="corpus" class="help-inline" /> </div> </div> <div class="form-group floatRight"> <input type="submit" value="send" class="btn btn-primary btn-sm"> </div> </div> <div class="row" style="color:#006600"> <label class="form-group col-md-1" for="corpus"><br>目前支持的语义解析领域有以下六个模块:</label> </div> <div class="row" style="color:#006600"> <label class="form-group col-md-1" for="corpus">新闻:</label> <div class="form-group col-md-2"> <br> app:news<br> 语料示例:<br> 今天的新闻<br> 有哪些娱乐新闻<br> 我要看新闻 <br> 新闻头条<br> </div> </div> <div class="row" style="color:#006600"> <label class="form-group col-md-1" for="corpus">星座:</label> <div class="form-group col-md-2"> <br> app:horoname<br> 语料示例:<br> 天蝎座的运势<br> 天蝎座的本月运势<br> 帮我查查明日运势,天蝎座的<br> </div> </div> <div class="row" style="color:#006600"> <label class="form-group col-md-1" for="corpus">公交:</label> <div class="form-group col-md-2"> <br> app:busline<br> 语料示例:<br> 615路的行车路线<br> 112路有哪些站点<br> 张江南环线停靠哪些站<br> 110路的公交路线<br> </div> </div> <div class="row" style="color:#006600"> <label class="form-group col-md-1" for="corpus">成语:</label> <div class="form-group col-md-2"> <br> app:idioms<br> 语料示例:<br> 告诉我画龙点睛是什么意思<br> 画龙点睛的含义<br> 有没有哪个成语叫龙什么的<br> 带龙的成语有哪些<br> </div> </div> <div class="row" style="color:#006600"> <label class="form-group col-md-1" for="corpus">笑话:</label> <div class="form-group col-md-2"> <br> app:joke<br> 语料示例:<br> 讲笑话<br> 给我讲个笑话吧<br> 来张趣图<br> 我要看笑话<br> </div> </div> <div class="row" style="color:#006600"> <label class="form-group col-md-1" for="corpus">解梦:</label> <div class="form-group col-md-2"> <br> app:oneiromancy<br> 语料示例:<br> 给我查查梦到了黄金有什么寓意<br> 昨天做梦梦到黄金了<br> 梦到黄金了有什么说法<br> 我昨天做了一个关于黄金的梦<br> </div> </div> </form:form> </div></body></html>
WEB-INF/views/success.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>智能语义解析——基于欧拉蜜开放平台</title><link href="<c:url value='/static/css/custom.css' />" rel="stylesheet"></link></head><body> <div class="success"> <div style="color:#006600"> news支持类别有:头条(importnews),娱乐(ent),体育(sports),军事(mil),金融(finance),财经(fortune),教育(edu),法治(fz),健康(health),社会(society)。<br> horoname支持查询的运势有:今日运势、明日运势、本周运势、本月运势、今年运势。<br> <br> app:模块名称。 <br> modifier:表示一句话的操作意图。 如语句 查看娱乐新闻 的意图为 查, 即用“query”来表示。 <br> slot:表示需要从语料中提取出来的关键字。 如语句 查看娱乐新闻 的意图已知道是 查,而查什么则是由slot来补充,即slot名字为type,值为从语料中提取出来的词语“娱乐”。<br> 更多详细介绍可参考: <a href="https://cn.olami.ai/wiki/?mp=nli&content=nli_response_result.html">https://cn.olami.ai/wiki/?mp=nli&content=nli_response_result.html</a> </div> <br> <br> ${answer} </div></body></html>
static/css/custom.css
.form-container { position:fiexd; width:30%; margin-left: 20px; margin-top: 20px; margin-bottom: 20px; padding: 10px; background-color: #E8E1E1; border: 1px solid #ddd; border-radius: 4px;} .form-group { display: inline-block; margin-bottom: 0; vertical-align: middle; }.input-sm { width: 400px; height: 30px; padding: 5px 10px; font-size: 12px; line-height: 1.5; border-radius: 3px;}.floatRight{ float:right; margin-right: 18px;}.row { margin-right: 15px; margin-left: 15px;}.col-md-1, .col-md-2 { position: relative; min-height: 1px; padding-right: 5px; padding-left: 5px;}.has-error{ color:red;}.success{ position:fiexd; width:50%; margin-left: 50px; margin-top:20px; padding: 20px; background-color: #E8E1E1; border: 1px solid #ddd; border-radius: 4px;}
7、添加初始化器类
package com.demo.configuration;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.ServletRegistration;import org.springframework.web.WebApplicationInitializer;import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;import org.springframework.web.servlet.DispatcherServlet;public class DemoInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext(); ctx.register(DemoConfiguration.class); ctx.setServletContext(container); ServletRegistration.Dynamic servlet = container.addServlet( "dispatcher", new DispatcherServlet(ctx)); servlet.setLoadOnStartup(1); servlet.addMapping("/"); }}
8、构建和部署应用程序
运行应用程序,访问URL:http://localhost:8080/SpringMVCDemoNLI
得到的初始页面如下图所示:
提交不正确输入时,会得到验证错误(在 message.properties 中用户定义的消息)
提交成功后跳转页面如下:
- SpringMVC+Maven开发最小“自然语言理解”项目攻略(附源码打包下载及详细说明)
- SpringMVC+Maven开发最小“自然语言理解”项目攻略(附源码打包下载及详细说明)
- SpringMVC+Maven开发最小“自然语言理解”项目攻略(附源码打包下载及详细说明)
- 理解Spring+SpringMVC+Hibernate开发流程,附一定源码(一)
- Maven+Mybatis+Spring+SpringMVC实现分页查询(附源码)
- Maven+Mybatis+Spring+SpringMVC实现分页查询(附源码)
- Maven+Mybatis+Spring+SpringMVC实现分页查询(附源码)
- Maven+Mybatis+Spring+SpringMVC实现分页查询(附源码)
- 下载文件-javaweb案例(内附代码详细说明)
- SpringMVC+BUI实现文件上传(附详解,源码下载)
- ASP.NET 3.5 新特性开发向导实践(附项目源码下载)- Part 1
- ASP.NET 3.5 新特性开发向导实践(附项目源码下载)- Part 2
- ASP.NET 3.5 新特性开发向导实践(附项目源码下载)
- 仿小米运动的蓝牙开源项目(附详细实现说明+源码)
- SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载
- SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载
- SpringMVC+Spring4+Mybatis3集成,开发简单Web项目+源码下载
- 口袋妖怪金心银魂详细图文攻略(上)及游戏下载
- Python 调用 opencv 处理图像
- 数据结构之算法时间复杂度
- 110. Balanced Binary Tree
- xss初识
- tensorflow ckpt文件转caffemodel时遇到的坑
- SpringMVC+Maven开发最小“自然语言理解”项目攻略(附源码打包下载及详细说明)
- 最长公共子串@Java
- MySQL 中 delete 语句的子查询限制
- 9 月 16 日极光开发者沙龙北京站 | 如何构建安全稳定的系统架构
- 2017-09-11 LeetCode_023 Merge k Sorted Lists
- 自媒体淘客写爆文的秘诀
- 【Java并发编程】之二:线程中断(含代码)
- (剑指offer)丑数,只包含因子2、3和5的数称作丑数
- 音视频封装格式、编码格式知识