'팁&테크/Coldfusion'에 해당되는 글 13건
- 2024.05.14 [Lucee CFHTTP] XML Request를 사용 할 때 주의해야 할 점.
- 2022.10.27 [Coldfusion] Header Override
- 2022.10.05 [Coldfusion] EncodeForHTML 이후 개행이 필요 할 때.
- 2021.07.09 [Coldfusion] Continue 사용 시 주의할 점.
- 2020.03.12 coldfusion 주의할 점. ㅠㅠ
- 2020.01.16 [Coldfusion] GET, POST 원시데이타 처리 getPageContext().getRequest()
- 2019.09.16 [Coldfusion] 같은 이름의 form element 처리 방법
- 2019.08.27 [Coldfusion] fileUpload 함수 처리전에 파일명을 확인해야 하는 경우
- 2019.02.21 여러개의 PDF 를 merge 하여 출력
- 2018.07.18 쓰레드 관련
[Lucee CFHTTP] XML Request를 사용 할 때 주의해야 할 점.
cfhttp(method='POST', charset='utf-8', url=apiUrl, result="response", clientcertpassword=qrCreds.ClientCertPassword, clientcert=qrCreds.ClientCertificate) {
//cfhttpparam(type='header', name='Content-Type', value='text/xml'); //If you use type='xml' in lucee, you should not set the 'Content-Type' header.
cfhttpparam(type='header', name='SOAPAction', value='http://services.escreen.com/RequestTicket');
cfhttpparam(type='xml', value=trim(requestData));
}
위와 같이 Lucee 에서는 type="xml" 로 내용을 전달 하는 경우 "Content-Type: text/xml" 을 전달 하지 말아야 한다.
이유는 type="xml" 일 때 자동으로 "Content-Type: text/xml" 를 추가 하여 수신 측에서 Invalid header 로 처리될 수 있다.
꼭 "Content-Type: text/xml" 을 수동으로 전달 하고자 한다면 type="xml" 을 type="body"로 해야 한다.
[Coldfusion] Header Override
header (CFHEADER) 를 사용 하면 header에 동일한 property가 존재해도 추가만 된다.
아래와 같이 사용하면 기존의 property 를 변경할 수 있다.
<cfscript>
pc = getPageContext().getResponse();
pc.setHeader("content-security-policy", "");
</cfscript>
[Coldfusion] EncodeForHTML 이후 개행이 필요 할 때.
rereplace(EncodeForHTML("내용"), "&##xa;&##xd;|&##xd;&##xa;|&##xa;|&##xd;", "<br>", "all")
[Coldfusion] Continue 사용 시 주의할 점.
<cfcontinue> 를 정상적이지 않은 곳에서 사용하게 되면 500 Internal Error 를 발생시키나.
<cfscript> 안에서 continue 를 잘못 사용하게 되면 그 뒤에 나오는 statement (cfscript 안의 statement만) 를 실행하지 않는 큰 문제가 생김.
예를 들어 아래 코드를 실행하게 되면 10 한번만 찍히게 됨.
<cfscript>
a = 10;
continue;
a = 20;
writeOutput(a);
a = 30;
</script>
<cfoutput>#a#</cfoutput>
이건 아래와 같은 경우의 continue 이후의 뒤에 나오는 모든 statement를 건너 뜀(cfscript 안의 statement만)
그래서 cfscript 마지막에 있는 abort 도 실행되지 않음.
<cfscript>
cfloop(query = sampleQuery) {
if(sampleQuery.column eq 1) {
continue;
}
}
abort;
</script>
cfloop 에는 continue, break 를 사용할 수 없으니 반드시 아래와 같이 사용할 것.
<cfscript>
for(var row in sampleQuery) {
if(row.column eq 1) {
continue;
}
}
abort;
</script>
coldfusion 주의할 점. ㅠㅠ
1. 변수 scope에 엄청나게 문제가 있음
cfloop(query = querySet) {
//querySet의 정식사용은 querySet.columnName 임
//단축 형태로 그냥 columnName으로 사용가능함
//그런데 단축 형태로 사용할때 큰 문제가 있음
writeOutput(columnName); //querySet.columnName 을 출력함
writeOutput(isDefined("columnName")); //yes(true) 존재함
writeOutput(isNull(columnName)); //yes(true) 존재하지 않음!!!!
}
cfloop(query = querySet) {
columnName = 10;
writeOutput(columnName); //10이 아닌 querySet.columnName 을 출력함!!!!
}
function test(required numeric columnName) {
...
cfloop(query = querySet) {
writeOutput(columnName);
//querySet.columnName가 아닌
//인자로 전달받은 arguments.columnName을 출력!!!!
}
}
2. serializeJSON 문제
test = {a: 0};
test.a = 1;
writeOutput(serializeJSON(test)); //{"A":1}
test.a += 1;
writeOutput(serializeJSON(test)); //{"A":2.0}
//연산을 하게되면 무조건 실수형으로 변환됨!!!
test = {a: "1.2", b: "3"};
writeOutput(serializeJSON(test)); //{"A":1.2,"B":3}
//string type 이라도 무조건 수치형으로 변환됨!!!!
3. 같은 이름의 form element 처리 문제
<input type="text" name="test" value="abc">
<input type="text" name="test" value="">
<input type="text" name="test" value="def">
<!-- 위의 경우 test = "abc,def"로 값이 수신됨 -->
<!-- 몇번째 변수의 값이 없는지 확인하지 못함 -->
<input type="text" name="test" value="abc,def">
<input type="text" name="test" value="">
<input type="text" name="test" value="">
<!-- test의 내용중 comma가 존재하면??? -->
<!-- test = "abc,def"로 값이 수신되어 변수 2개에서 수신된것 처럼 됨 -->
[Coldfusion] GET, POST 원시데이타 처리 getPageContext().getRequest()
requestObj = getPageContext().getRequest();
writeDump(requestObj.getParameter('a')); //일반 변수 시 사용, a 변수에 대한 처음 한개의 값을 가져옴
writeDump(requestObj.getParameterValues('a')); //같은 변수명의 값이 여러개인 경우 사용, a 변수에 대한 모든 값을 가져옴(배열)
writeDump(requestObj.getParameterMap()); //전체 수신 data를 struct로 가져옴.
writeDump(requestObj);
//getParameterMap()의 struct는 data.key 형태로 사용이 되지 않는다. 반드시 data['key']로 사용해야 하고.
//각 key에 들어있는 array는 cf11용 메소드 방식이 사용되지 않는다 ㅡㅡ;
//data['key'].len() -> 오류발생, arraylen(data['key']) 형태로 써야한다.
참고 : https://wyseburn.tistory.com/entry/%EC%BD%9C%EB%93%9C%ED%93%A8%EC%A0%84Coldfusion-%EB%A9%94%EB%AA%A8
[Coldfusion] 같은 이름의 form element 처리 방법
Coldfusion에서 같은 이름의 form element를 전송하면 자동으로 list 형태(,콤마 구분)으로 만들어주는데..
이게 아주 병신같다. form value에 comma가 들어가면 100% 오작동 한다. 아주 쓰레기 언어임.
일반 form 전송인 경우 아래와 같이 하면 array로 받아 올 수 있다.
<cfdump var="#getPageContext().getRequest().getParameterValues('변수명')#"/>
multipart/form-data 인 경우에는 form.getPartsArray()를 사용해야한다.
Coldfusino 서버인 경우
<cfset tmpPartsArray = Form.getPartsArray() />
<cfif IsDefined("tmpPartsArray")>
<cfloop array="#tmpPartsArray#" index="tmpPart">
<cfif tmpPart.isParam() AND tmpPart.getName() eq '변수명'>
<cfoutput>#EncodeForHTML(tmpPart.getStringValue())#</cfoutput>
</cfif>
</cfloop>
</cfif>
Lucee 서버인 경우
var tmpPartsArray = form.getFileItems();
if(!isNull(tmpPartsArray)) {
for(var file in tmpPartsArray) {
if(arguments.formFieldName eq file.getFieldName()) {
return file.getName();
}
}
}
[Coldfusion] fileUpload 함수 처리전에 파일명을 확인해야 하는 경우
string function getUploadFileName(required string formFieldName)
{
var tmpPartsArray = Form.getPartsArray();
var clientFileName = "";
if (!isNull(tmpPartsArray)) {
for (var tmpPart in tmpPartsArray) {
if (tmpPart.isFile() AND tmpPart.getName() EQ arguments.formFieldName) {
return tmpPart.getFileName();
}
}
}
return "";
}
여러개의 PDF 를 merge 하여 출력
<cfdocument name="aaa" format="pdf">
abcd
</cfdocument>
<cfpdf action="merge" name="abc">
<cfpdfparam source="aaa">
<cfpdfparam source="#expandPath("/testPDF4.pdf")#">
<cfpdfparam source="#expandPath("/testPDF11.pdf")#">
</cfpdf>
<cfcontent type="application/pdf" variable="#ToBinary( abc )#" reset="true">
쓰레드 관련
<!--- Create the thread object --->
<cfobject type="JAVA" action="Create" name="thread" class="java.lang.Thread">
<!--- Get all stack traces from the thread object --->
<cfset stackTrace = thread.getAllStackTraces()>
<!--- Convert the entrySet into an array --->
<cfset stackArray = stackTrace.entrySet().toArray()>
<cfoutput>
<!--- Loop over the entrySet array --->
<cfloop from="1" to="#ArrayLen(stackArray)#" index="sIndex">
<!--- Get the current thread values --->
<cfset thisThread = stackArray[sIndex].getValue()>
<!--- Loop over current thread values --->
<cfloop from="1" to="#ArrayLen(thisThread)#" index="tIndex">
<!--- Get the filename for this thread --->
<cfset thisThreadFile = thisThread[tIndex].getFileName()>
<!--- If the file name contains .cfm output it --->
<cfif isDefined("thisThreadFile") AND (thisThreadFile CONTAINS ".cfm" OR thisThreadFile CONTAINS ".cfc")>
#thisThreadFile#<br>
</cfif>
</cfloop>
</cfloop>
</cfoutput>
<cfscript>
function getActiveThreadsRunning(adminPassword) hint="Get all active threads running currently" {
var threadArrray = arrayNew(1);
//Creating Admin Object
var adminObject = createobject("component","cfide.adminapi.administrator");
//Creating Server Monitoring Object
var monitorObject = createobject("component","cfide.adminapi.servermonitoring");
//Login to Admin API
adminObject.login(arguments.adminPassword);
//Get all Active Thread info
threadArrray = monitorObject.getAllActiveCFThreads();
//log out from the admin API login
adminObject.logout();
return threadArrray;
}
function killActiveThread(adminPassword, threadName) hint="Kill specified thread which are running" {
//Creating Admin Object
var adminObject = createobject("component","cfide.adminapi.administrator");
//Creating Serbver Monitoring Object
var monitorObject = createobject("component","cfide.adminapi.servermonitoring");
//Login to Admin API
adminObject.login(arguments.adminPassword);
//kill thread now by calling abortCFThread. It accepts thread name
var killedThread = monitorObject.abortCFThread(arguments.threadName);
//logout from admin API
adminObject.logout();
// return true/false based on response.
return killedThread;
}
</cfscript>