grails 调用层次堆栈

本文详细介绍了Grails框架中请求处理的具体流程,从控制器的帮助类SimpleGrailsControllerHelper开始,到请求的最终处理,包括了Spring框架组件的交互过程。通过跟踪源代码的方式展示了Grails如何处理HTTP请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.handleAction(SimpleGrailsControllerHelper.java:368)
org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.executeAction(SimpleGrailsControllerHelper.java:232)
org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.handleURI(SimpleGrailsControllerHelper.java:190)
org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsControllerHelper.handleURI(SimpleGrailsControllerHelper.java:129)
org.codehaus.groovy.grails.web.servlet.mvc.SimpleGrailsController.handleRequest(SimpleGrailsController.java:73)
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
org.codehaus.groovy.grails.web.servlet.GrailsDispatcherServlet.doDispatch(GrailsDispatcherServlet.java:292)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:719)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:644)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:549)
javax.servlet.http.HttpServlet.service(HttpServlet.java:707)
javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:70)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:646)
org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:436)
org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:374)
org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:302)
org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:298)
org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:264)
org.codehaus.groovy.grails.web.util.WebUtils.forwardRequestForUrlMappingInfo(WebUtils.java:255)
org.codehaus.groovy.grails.web.mapping.filter.UrlMappingsFilter.doFilterInternal(UrlMappingsFilter.java:183)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.obtainContent(GrailsPageFilter.java:245)
org.codehaus.groovy.grails.web.sitemesh.GrailsPageFilter.doFilter(GrailsPageFilter.java:134)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.codehaus.groovy.grails.web.servlet.filter.GrailsReloadServletFilter.doFilterInternal(GrailsReloadServletFilter.java:104)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.codehaus.groovy.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:69)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.codehaus.groovy.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:69)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:76)
org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:237)
org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:849)
org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:583)
org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:454)
java.lang.Thread.run(Thread.java:619)
 
/** * Created by RoWe on 2025/04/29 * 创建关联关系接口 */ package com.elite.groovy.callback import com.elite.groovy.util.EliteBean import com.elite.groovy.util.Util import net.sf.json.JSONObject import org.apache.commons.logging.Log import org.apache.commons.logging.LogFactory import org.apache.http.HttpHost import org.apache.http.auth.AuthScope import org.apache.http.auth.UsernamePasswordCredentials import org.apache.http.client.config.RequestConfig import org.apache.http.conn.ssl.NoopHostnameVerifier import org.apache.http.impl.client.BasicCredentialsProvider import org.apache.http.impl.client.CloseableHttpClient import org.apache.http.impl.client.HttpClients import org.apache.http.ssl.SSLContexts import org.apache.http.util.EntityUtils import javax.net.ssl.SSLContext import javax.servlet.http.HttpServletRequest import javax.servlet.http.HttpServletResponse //在工单页面选择手机选项并进行外呼时, CRM系统根据当前工单对应归属机构信息, 传入已经报备好的主叫号调用创建关联关系接口,获取隐私号telX,记录当前创建关联关系信息并将获取的隐私号telX连同调用接口的主叫号一起传给CC平台实现外呼 public class OCNAssociationAdd implements ServiceBackInvoke { private static final Log log = LogFactory.getLog(OCNAssociationAdd.class); otherUtil otherUtil = new otherUtil(); // 代理配置常量 private static final String PROXY_HOST = "wsproxy-dsu.sssit.com" private static final int PROXY_PORT = 8080 private static final String PROXY_USER = "cc-groovy" private static final String PROXY_PASS = "" // 替换为实际密码 public String doCallBack(EliteBean eliteBean, HttpServletRequest request, HttpServletResponse response) { request.setCharacterEncoding("UTF-8"); response.setCharacterEncoding("UTF-8"); response.setContentType("application/json;charset=UTF-8"); String requestBody = Util.getRequestBody(request, "UTF-8"); String appCode = ""; String appMessage = ""; String dataSource = "dataSource"; JSONObject responseJson = new JSONObject(); JSONObject dataJson = new JSONObject(); CloseableHttpClient httpClient = null; try { JSONObject requestJson = JSONObject.fromObject(requestBody); // 必须每次请求的唯一标识 String requestId = UUID.randomUUID(); List appList = eliteBean.chaxun_sql("SELECT appId,appKey,telA FROM OCNApp WHERE method ='OCNAdd'", dataSource); String appId = appList[0].getAt("appId"); String appKey = appList[0].getAt("appKey"); //主叫号 4008333000 String telA = appList[0].getAt("telA"); //客户号码 String telB = requestJson.getString("telB"); //指定地区 String areaCode = requestJson.getInt("areaCode"); // log.debug("telB",telB); // log.debug("areaCode",areaCode); List AreaInfoList = eliteBean.chaxun_sql("SELECT CCCityCode FROM AreaInfo WHERE areaCode='$areaCode'", dataSource); String CCCityCode = AreaInfoList[0].getAt("CCCityCode"); //是否严格匹配 经过三星老师定版为 0 int areaMatchMode = 0; //创建时间戳 long creTimeStemp = System.currentTimeMillis(); //有效时间 暂定5分钟,单位为毫秒 和后续删除关联关系有关 int expiration = 300000; //long tempStemp=System.currentTimeMillis(); //seqId string(32) 必须绑定关系的序列号 String seqId = ""; //telX string(20) 条件X 号码管理方式为Random 时,系统随机分配的号码 String telX = ""; int InsertOCNAssociation = eliteBean.update( "INSERT INTO OCNAssociation (requestId,telA,telB,areaCode,areaMatchMode,creTimeStemp,expiration) VALUES('${requestId}','${telA}','${telB}','${areaCode}','${areaMatchMode}','${creTimeStemp}','${expiration}') ", dataSource); JSONObject req = new JSONObject(); req.put("requestId", requestId); req.put("telA", telA); req.put("telB", telB); req.put("CCCityCode", CCCityCode); req.put("areaMatchMode", areaMatchMode); req.put("expiration", expiration); OCNRUtils OCNRUtils = new OCNRUtils(); // sm4密钥:将appKey转成md5再取中间16位 String sm4Key = OCNRUtils.get16MD5(appKey); // sm4加密 OCNRUtils.sign(req, appId, appKey); // 设置加密后的member //req.put("member", membersEncrypted); Map headMap = new HashMap(); headMap.put("Content-Type", "application/json"); headMap.put("charset", "utf-8"); List urlSql = eliteBean.chaxun_sql("select url,method from sysc_interface where method ='OCNAdd'", "dataSource"); if (urlSql != null && !urlSql.empty) { // 创建带代理的HTTP客户端 httpClient = createProxyHttpClient(); // 执行POST请求 String webService = "https://ystx.wo.com.cn:19090/privateapi/axb/create"; String responseInfo = doProxyPost(httpClient, webService, req.toString()); // 处理响应 responseJson = JSONObject.fromObject(responseInfo); appCode = responseJson.getString("code"); appMessage = responseJson.getString("msg"); dataJson = responseJson.getJSONObject("data"); responseJson.put('appCode', appCode); responseJson.put('appMessage', appMessage); return responseJson.toString(); } else { appCode = "222"; appMessage = "接口地址维护异常"; } appCode = "222"; appMessage = "测试成功"; responseJson.put('appCode', appCode); responseJson.put('appMessage', appMessage); responseJson.put('requestId', requestId); //responseJson.put('telX', telX); return responseJson; } catch (Exception e) { log.error("e:", e); appCode = "999"; appMessage = "系统异常,请稍后重试"; responseJson.put('appCode', appCode); responseJson.put('appMessage', appMessage); responseJson.put('e', e); return responseJson; } finally { try { if (httpClient != null) httpClient.close(); } catch (Exception e) { log.error("关闭HTTP客户端失败:", e); } } } /** * 创建带代理的HTTP客户端 */ private CloseableHttpClient createProxyHttpClient() { // 代理凭证提供器 def credsProvider = new BasicCredentialsProvider() credsProvider.setCredentials( new AuthScope(PROXY_HOST, PROXY_PORT), new UsernamePasswordCredentials(PROXY_USER, PROXY_PASS) ) // SSL上下文(信任所有证书 - 仅测试环境使用) SSLContext sslContext = SSLContexts.custom() .loadTrustMaterial(null, { certs, authType -> true }) .build() // 请求配置 def requestConfig = RequestConfig.custom() .setProxy(new HttpHost(PROXY_HOST, PROXY_PORT)) .setConnectTimeout(30000) // 30秒连接超时 .setSocketTimeout(60000) // 60秒数据传输超时 .build() // 创建HTTP客户端 return HttpClients.custom() .setDefaultCredentialsProvider(credsProvider) .setSSLContext(sslContext) .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE) .setDefaultRequestConfig(requestConfig) .build() } /** * 通过代理执行POST请求 * @param client HTTP客户端 * @param url 目标URL * @param body 请求体JSON字符串 */ private String doProxyPost(CloseableHttpClient client, String url, String body) { def httpPost = new org.apache.http.client.methods.HttpPost(url) // 设置请求头 httpPost.setHeader("Content-Type", "application/json") httpPost.setHeader("charset", "utf-8") // 设置请求体 httpPost.setEntity(new org.apache.http.entity.StringEntity(body, "UTF-8")) // 执行请求 def response = client.execute(httpPost) def entity = response.getEntity() try { return EntityUtils.toString(entity, "UTF-8") } finally { EntityUtils.consume(entity) } } }代码报错500的原哟
07-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bluedest

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值