ServletAPI 调用方式
元数据7GA以及之前的模式:
java
<bean id="browser.do" parent="dispatcher" scope="prototype" class="com.primeton.dgs.web.app.browse.BrowseCommand" />
class BrowseCommand {
//request 由此注入
public void init(HttpServletRequest request, HttpServletResponse response,
ServletConfig servletConfig) throws Exception {
super.init(request, response, servletConfig);
isbssBs = (ISBrowserSysService) getSpringBean(ISBrowserSysService.SPRING_NAME);
}
public void browserSysClassify() throws Exception {
// 处理请求,相应内容
String name = request.getParameter("name"); // 获取参数
}
}
前端调用:
properties
/dgs/browser?invoke=browserSysClassify&name=DGS
问题:
采用VUE前后端分离架构时,传参一般都采用 Payload Parameters(JSON)
的方式,而不是 Query Parameters
的方式。
以 curl 为例,QueryParameter 的方式如下:
shell
curl -X POST -d 'invoke=browserSysClassify' -d 'name=DGS' /dgs/browser
PayloadParameter 的方式如下(Payload 的参数时直接传 JSON):
shell
curl -X POST -H 'Content-Type: application/json' \
-d '{"invoke":"browserSysClassify", "name": "DGS"}' /dgs/browser
RESTFul API
判断 Content-Type 为 application/json
则调用为REST API。
java
BufferedReader reader = request.getReader();
String header = StringUtils.trimToNull(request.getHeader("Content-Type"));
if("application/json".equalsIgnoreCase(header)) {
String json = IOUtils.toString(reader);
if(StringUtils.isBlank(json)) {
json = "{}";
}
JSONObject jsonObject = JSON.parseObject(json);
// 调用 api
}
通过构造一个 Request 的包装类,把 QueryParameter 和 PayloadParameter 的参数合并。元数据接口是通过 request.getParameter("name") 的方式获得参数。这样无论两种参数传递方式,后台都可以获得参数。
java
public class MetaCubeHttpServletRequestWrapper extends HttpServletRequestWrapper {
/**
* 元数据部分参数是从 payload 获得的,装饰 RestFull API
*/
protected final Map<String, Object> payloadParameters = new HashMap<>();
public MetaCubeHttpServletRequestWrapper(HttpServletRequest request, Map<String, Object> payloadParameters) {
super(request);
this.payloadParameters.putAll(payloadParameters);
}
@Override
public String getParameter(String name) {
String parameter = super.getParameter(name);
// 获取参数,如果 form 中为空,则从 payload 中获取
return parameter == null ? (String)payloadParameters.get(name) : parameter;
}
@Override
public String[] getParameterValues(String name) {
String[] parameterValues = super.getParameterValues(name);
// 获取参数,如果 form 中为空,则从 payload 中获取
return parameterValues == null ? new String[]{ (String)payloadParameters.get(name)} : parameterValues;
}
}
对于包装的 MetaCubeHttpServletRequestWrapper 在调用后台方法时,直接作为 request 参数传递,这样 Servlet 在 getParameter() 时,调用的是 MetaCubeHttpServletRequestWrapper 的结果。
java
HttpServletRequest requestWrapper = new MetaCubeHttpServletRequestWrapper(request, jsonObject);
//获取 bean
AbstractCommand cmd = CommandFactory.getInstance().getCommand(path);
if(cmd != null) {
cmd.init(requestWrapper, response, getServletConfig());
next = cmd.execute();
}
对于前端调用,RESTFul URL为:
shell
curl -X POST -H 'Content-Type: application/json' \
-d '{"name": "DGS"}' /dgs/appsapi/browser/browserSysClassify
原生的调用方式 URL为:
shell
curl -X POST -H 'Content-Type: application/json' \
-d 'name=DGS' /dgs/appsapi/browser/browserSysClassify
# 或
curl -X GET /dgs/appsapi/browser/browserSysClassify?name=DGS
调用的路由参数,都在 URL 中,接口参数,则在 Payload 中。无论何种方式,都可适应。