问题背景
maven项目包括多个子模块,类似下图:
现在【web】模块某个类想要调用【service】模块的某个类的某个方法。
如果直接通过@Autowired注入【service】模块的某个类,会发现编译器根本找不到那个类,因为跨模块了。
解决方法
方法1
在【web】模块的pom.xml中添加依赖,引入【service】模块,类似:
<dependency>
<groupId>com.***.***</groupId>
<artifactId>service</artifactId>
</dependency>
添加完刷新maven,然后就能在【web】模块中注入【service】模块的类了。
方法2
方法1通常情况下就能解决问题,但是若之前【service】模块已经引入了【web】模块,此时再根据方法1在【web】中引入【service】的话,就会出现循环依赖,启动报错。
此时可以采用直接调用接口的方法:
假如我们在【web】模块中想调用的就是【service】模块中的"check"方法(如下),我们无法像方法1中直接调用check方法时,可以选择直接调用“api/v1/bbb/aaa”这个接口来达到目的
@GetMapping("api/v1/bbb/aaa")
@ResponseBody
public void getCheck(@RequestParam Map<String,String> map){
String ttt= JSONObject.toJSONString(map);
check(ttt);
}
直接调用接口的步骤:
- 定义接口地址(不这么定义,调用时直接写也行)
public String getURL(){
//port是访问端口号,***是访问的context-path,自己调整吧
return "http://127.0.0.1:" + port + "/***/api/v1/bbb/aaa";
}
大家应该注意到上述接口地址并没带参数,所以还需要写一个工具类用来拼接请求参数。
这个是get请求,所以工具类如下:
public Object sendGetRequest(String url, Map<String, String> requestLine)
throws HttpResponseOfInterfaceException {
HttpURLConnection httpConn = null;
InputStreamReader inpRead = null;
BufferedReader inputStreamOfHttpRsp = null;
try {
StringBuilder requestUrl = new StringBuilder(url);
if (requestLine != null && !requestLine.isEmpty()) {
// 如果请求参数不为空,则在请求时添加上这些参数
requestUrl.append("?");
Set<String> paramKeys = requestLine.keySet();
Iterator<String> it = paramKeys.iterator();
String paramKey;
String paramValue;
while (it.hasNext()) {
paramKey = it.next();
paramValue = StringUtils.defaultIfEmpty(requestLine.get(paramKey),"");
requestUrl.append(paramKey).append("=").append(URLEncoder.encode(paramValue,"UTF-8"));
if (it.hasNext()) {
requestUrl.append("&");
}
}
}
String messageId = UUID.randomUUID().toString().replaceAll("-" , "");
InterfaceLog.request(messageId, requestUrl == null ? "无地址" : requestUrl.toString(),"GET",
requestLine == null ? "无参数" : requestLine.toString());
URL objUrl = new URL(requestUrl.toString());
httpConn = (HttpURLConnection) objUrl.openConnection();
// 添加请求头部
httpConn.setRequestMethod("GET");
int rspCode = httpConn.getResponseCode();
inpRead = getInputStreamReader(httpConn);
inputStreamOfHttpRsp = new BufferedReader(inpRead);
String inputLine;
StringBuffer httpRspStringBuffer = new StringBuffer();
while (null != inputStreamOfHttpRsp && (inputLine = inputStreamOfHttpRsp.readLine()) != null) {
httpRspStringBuffer.append(inputLine);
}
InterfaceLog.response( messageId, requestUrl.toString(), httpConn.getRequestMethod(), rspCode, ObjectUtils.toString(httpRspStringBuffer));
Object rspResult;
try{
rspResult = JSON.parseObject(httpRspStringBuffer.toString());
} catch (Exception e){
rspResult = JSON.parseArray(httpRspStringBuffer.toString());
}
checkRespValid(rspResult);
return rspResult;
} catch (MalformedURLException e) {
logger.error("GET-Http请求Url异常--->", e);
} catch (ProtocolException e) {
logger.error("协议异常--->", e);
} catch (IOException e) {
logger.error("GET-Http请求过程中IO异常--->", e);
} catch (Exception e){
logger.error("GET请求中其他异常", e);
} finally {
try {
if (inputStreamOfHttpRsp != null) {
inputStreamOfHttpRsp.close();
}
if (inpRead != null) {
inpRead.close();
}
if (httpConn != null) {
httpConn.disconnect();
}
} catch (IOException e) {
logger.error("关闭资源失败--->", e);
}
}
throw new HttpResponseOfInterfaceException("GET请求失败");
}
(以上代码包含一些自定义内容,请自行修改)
定义完拼接请求参数的方法,我们就可以在【web】模块中进行接口调用啦:
Map<String, String> requestParam = new HashMap<>();
requestParam.put("***", ***);
sendGetRequest(getURL(),requestParam);