NCC的http接口實現方案
一. 功能描述
在實際應用中,開發雙方希望無session訪問接口,使用nccloud的restful風格的action無法滿足業務要求,需要開發一套支持無session訪問的接口訪問方式。由於嘗試使用NC6系列開發webservise的方式行不通,所以可以參照以下介紹的方式開發接口,如有問題,可在以下的方式上進行優化。
此處我設置的url-patten是*.ws,例如我請求的url是http://localhost:80/nccloud/web/hrwa/kpiassign/action/PlanDataReqAction.ws ,那麼我這個請求的後端對應的類是nccloud.web.hrwa.kpiassign.action.PlanDataReqAction。需要注意的是,請求的Header必須包括Host,如圖:
二. 實現方式
- 編寫filter攔截器,可根據需求加入一些攔截功能
package nccloud.framework.core;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nccloud.framework.core.env.Locator;
import nccloud.framework.core.log.ILog;
import nccloud.framework.core.log.ILogFactory;
import nccloud.framework.web.action.entry.Result;
public class PlatformInterfaceFilter implements Filter {
public PlatformInterfaceFilter() {
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws UnsupportedEncodingException {
ILog logger = ((ILogFactory) Locator.find(ILogFactory.class)).getLog("nccloud");
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
try {
// start攔截器攔截操作
// end攔截器攔截操作
chain.doFilter(req, res);
} catch (Exception e) {
String msg = URLEncoder.encode(e.getMessage(), "UTF-8");
res.setHeader("EXCEPTION", msg);
res.setStatus(500);
logger.error(e);
}
}
public void init(FilterConfig arg0) throws ServletException {
}
}
- 編寫請求入口servlet,所以滿足url-patten的都會進到這個請求,url-patten在web.xml中配置
package nccloud.framework.core;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nc.vo.ml.NCLangRes4VoTransl;
import nccloud.framework.core.json.IJson;
import nccloud.framework.core.log.Log;
import nccloud.framework.web.action.entry.Dispatcher;
import nccloud.framework.web.action.entry.Result;
import nccloud.framework.web.container.GZip;
import nccloud.framework.web.container.HttpOperator;
import nccloud.framework.web.json.JsonFactory;
import org.apache.commons.lang3.StringUtils;
public class PlatformInterfaceController extends HttpServlet {
private static final long serialVersionUID = -832392821095654820L;
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getParameter("data");
HttpServletRequest request = req;
String uri = request.getRequestURI();
if (StringUtils.isNotEmpty(uri)) {
String className = uri.replaceAll("/", ".").replaceAll(".ws", "");
className = className.substring(1, className.length());
try {
Class clz = Class.forName(className);
// 根據URI生成處理類
IInterfaceAction ta = (IInterfaceAction) clz.newInstance();
Object value = ta.execute(req);
Result result = new Result();
result.setData(value);
if (result != null) {
IJson gson = JsonFactory.create();
resp.getWriter().write(gson.toJson(result));
}
} catch (Exception e) {
resp.getWriter().write(getErrorMsg(e));
}
}
}
private void writeJson(String json, HttpServletResponse resp) {
try {
GZip zip = new GZip();
json = zip.zip(json);
resp.getWriter().write(json);
} catch (Exception ex) {
Log.error(ex);
}
}
private void writeJson(Result result, HttpServletResponse resp) {
String json = null;
try {
IJson gson = JsonFactory.create();
json = gson.toJson(result);
GZip zip = new GZip();
json = zip.zip(json);
resp.getWriter().write(gson.toJson(json));
} catch (Exception ex) {
Log.error(ex);
}
}
public String getErrorMsg(Exception ex) {
String stack = getStackTrace(ex);
StringBuilder sb = new StringBuilder();
sb.append("{");
sb.append(" \"data\": null,");
sb.append(" \"error\": {");
sb.append(" \"exceptionClass\":");
sb.append("\"");
sb.append(ex.getClass().getName());
sb.append("\"");
sb.append(",");
sb.append(NCLangRes4VoTransl.getNCLangRes().getStrByID("1501001_0", "01501001-0199"));
sb.append(" \"stack\":\"");
sb.append(stack);
sb.append("\",");
sb.append(" \"status\": 500");
sb.append(" },");
sb.append(" \"success\": false");
sb.append("}");
return sb.toString();
}
private String getStackTrace(Throwable th) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw, true);
th.printStackTrace(pw);
return sw.getBuffer().toString();
}
}
- 將以上的filter和servlet配置到web.xml中,web.xml的路徑爲:ncchome\hotwebs\nccloud\WEB-INF\web.xml
<!--PlatformInterfaceFilter -->
<filter>
<filter-name>PlatformInterfaceFilter</filter-name>
<filter-class>nccloud.framework.core.PlatformInterfaceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>PlatformInterfaceFilter</filter-name>
<url-pattern>*.ws</url-pattern>
</filter-mapping>
<!--PlatformInterfaceFilter -->
<!--PlatformInterfaceController -->
<servlet>
<servlet-name>PlatformInterfaceController</servlet-name>
<servlet-class>nccloud.framework.core.PlatformInterfaceController</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>PlatformInterfaceController</servlet-name>
<url-pattern>*.ws</url-pattern>
</servlet-mapping>
<!--PlatformInterfaceController -->
配置完成後編寫一個接口規範,之後所有的類似請求都必須實現這個接口
package nccloud.framework.core;
import javax.servlet.http.HttpServletRequest;
public abstract interface IInterfaceAction {
public abstract Object execute(HttpServletRequest req);
}
- 實現示例
package nccloud.web.hrwa.kpiassign.action;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import nc.bs.framework.common.NCLocator;
import nc.bs.logging.Logger;
import nc.itf.uap.IUAPQueryBS;
import nccloud.framework.core.IInterfaceAction;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class TestAction implements IInterfaceAction {
private String param;
public String getParam(HttpServletRequest req) {
param = "";
try {
BufferedReader reader = req.getReader();
String line;
while ((line = reader.readLine()) != null){
param = param.concat(line);
}
} catch (IOException e1) {
Logger.error(e1);
e1.printStackTrace();
}
return param;
}
@Override
public Object execute(HttpServletRequest req, HttpServletResponse resp) {
String param = getParam(req);
JSONObject paramJson = JSON.parseObject(param);
IUAPQueryBS queryBS = NCLocator.getInstance().lookup(IUAPQueryBS.class);
String optType = paramJson.getString("optType");
List<Map<String, Object>> mapList = new ArrayList<>();
return mapList;
}
}
注意:此處數據處理需用IUAPQueryBS接口和IVOPersistence接口操作數據,用其他接口可能會導致token is null的錯誤