--- src/main/java/itn/com/cmm/interceptor/InterceptorHandler.java
+++ src/main/java/itn/com/cmm/interceptor/InterceptorHandler.java
... | ... | @@ -16,136 +16,137 @@ |
| 16 | 16 |
import itn.com.cmm.LoginVO; |
| 17 | 17 |
import itn.com.cmm.util.XssFilterUtil; |
| 18 | 18 |
|
| 19 |
-public class InterceptorHandler extends HandlerInterceptorAdapter{
|
|
| 19 |
+public class InterceptorHandler extends HandlerInterceptorAdapter {
|
|
| 20 | 20 |
|
| 21 |
- @Override |
|
| 21 |
+ @Override |
|
| 22 | 22 |
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
| 23 |
- |
|
| 24 |
- //SameSite 설정하기 |
|
| 25 |
- addSameSite(response , "None"); |
|
| 26 |
- |
|
| 27 |
- /** |
|
| 28 |
- * URL 호출 전 넘어오는 파라미터 체크 |
|
| 29 |
- * request로 넘어오는 모든 파라미터 데이터를 검사하여 XSS 문자가 포함되어 있으면 메인화면으로 튕김 |
|
| 30 |
- * */ |
|
| 31 |
- boolean returnSts1 = true; |
|
| 32 |
- Enumeration e = request.getParameterNames(); |
|
| 33 |
- while ( e.hasMoreElements() ){
|
|
| 34 |
- String name = (String) e.nextElement(); |
|
| 35 |
- System.out.println("@@@@ "+name.toLowerCase());
|
|
| 36 |
- if(!name.toLowerCase().contains("url")
|
|
| 37 |
- && !name.toLowerCase().contains("pagetype")
|
|
| 38 |
- && !name.toLowerCase().contains("searchsortcnd")
|
|
| 39 |
- && !name.toLowerCase().contains("imgfilepath")
|
|
| 40 |
- && !name.toLowerCase().contains("msgpreview")
|
|
| 41 |
- && !name.toLowerCase().contains("smstxtarea")
|
|
| 42 |
- && !name.toLowerCase().contains("smstxt")
|
|
| 43 |
- && !name.toLowerCase().contains("rep1list")
|
|
| 44 |
- && !name.toLowerCase().contains("rep2list")
|
|
| 45 |
- && !name.toLowerCase().contains("rep3list")
|
|
| 46 |
- && !name.toLowerCase().contains("rep4list")
|
|
| 47 |
- && !name.toLowerCase().contains("namelist")
|
|
| 48 |
- && !name.toLowerCase().contains("memolist")
|
|
| 49 |
- && !name.toLowerCase().contains("info1list")
|
|
| 50 |
- && !name.toLowerCase().contains("info2list")
|
|
| 51 |
- && !name.toLowerCase().contains("info3list")
|
|
| 52 |
- && !name.toLowerCase().contains("info4list")
|
|
| 53 |
- && !name.toLowerCase().contains("nttcn")
|
|
| 54 |
- && !name.toLowerCase().contains("ci")
|
|
| 55 |
- && !name.toLowerCase().contains("certdi")
|
|
| 56 |
- && !name.toLowerCase().contains("di")
|
|
| 57 |
- && !name.toLowerCase().contains("mbldn")
|
|
| 58 |
- && !name.toLowerCase().contains("mberid")
|
|
| 59 |
- && !name.toLowerCase().contains("userid")
|
|
| 60 |
- && !name.toLowerCase().contains("id_text")
|
|
| 61 |
- && !name.toLowerCase().contains("mberemailadres")
|
|
| 62 |
- && !name.toLowerCase().contains("recommendid")
|
|
| 63 |
- && !name.toLowerCase().contains("mbernm")
|
|
| 64 |
- && !name.toLowerCase().contains("varvallist")
|
|
| 65 |
- && !name.toLowerCase().contains("templatecontent")
|
|
| 66 |
- && !name.toLowerCase().contains("buttonvolist")
|
|
| 67 |
- ) {
|
|
| 68 |
- //파라미터 중에 URL 주소를 넘겨주는 부분이 있어서 해당 부분에것 select~, update~, delete~ 로 시작하는 주소경로가 있어서 제외처리를 하였음 |
|
| 69 |
- String[] values = request.getParameterValues(name); |
|
| 70 |
- |
|
| 71 |
- //HTML 태그 관련 부분이 들어있으면 필터링 해주는 정규식 <> ~ </> 구문 찾아줌 |
|
| 72 |
- //Pattern regex = Pattern.compile("<(/)?([a-zA-Z]*)(\\\\s[a-zA-Z]*=[^>]*)?(\\\\s)*(/)?>");
|
|
| 73 |
- //23.7.18 이지우 - XSS 필터링을 위한 정규식 수정 |
|
| 74 |
- Pattern regex = Pattern.compile("<[^ㄱ-ㅎㅏ-ㅣ가-힣<>]+>");
|
|
| 75 |
- for (String value : values) {
|
|
| 76 |
- |
|
| 77 |
- //정규식과 동일한 패턴인지 비교해준다. |
|
| 78 |
- Matcher matcher = regex.matcher(value); |
|
| 79 |
- boolean rsltMatch = matcher.find(); |
|
| 80 |
- |
|
| 81 |
- //패턴이 일치하면 오류 발생 |
|
| 82 |
- if(rsltMatch) {
|
|
| 83 |
- |
|
| 84 |
- returnSts1 = false; |
|
| 85 |
- System.out.println("+++++++++++++++++++++++++++XSS Html 필터 처리 Filter Start::: ");
|
|
| 86 |
- System.out.println("name="+ name + ", value="+ value);
|
|
| 87 |
- System.out.println("+++++++++++++++++++++++++++XSS Html 필터 처리 Filter End::: ");
|
|
| 88 |
- response.sendRedirect(request.getContextPath() + "/"); |
|
| 89 |
- |
|
| 90 |
- } |
|
| 91 |
- |
|
| 92 |
- boolean returnSts = XssFilterUtil.cleanXSS(value); |
|
| 93 |
- if(!returnSts) {//XSS 문자 체크 결과 false일 경우 메인화면으로 이동
|
|
| 94 |
- returnSts1 = returnSts; |
|
| 95 |
- System.out.println("+++++++++++++++++++++++++++XSS 필터 처리 Filter::: ");
|
|
| 96 |
- System.out.println("name="+ name + ", value="+ value);
|
|
| 97 |
- System.out.println("+++++++++++++++++++++++++++XSS 필터 처리 Filter End::: ");
|
|
| 98 |
- response.sendRedirect(request.getContextPath() + "/"); |
|
| 99 |
- } |
|
| 100 |
- } |
|
| 101 |
- } |
|
| 102 |
- } |
|
| 103 |
- |
|
| 104 |
- if(!returnSts1) {//XSS 포함문자가 있는경우 메인화면으로 이동시킨다.
|
|
| 105 |
- response.sendRedirect(request.getContextPath() + "/"); |
|
| 106 |
- return true; |
|
| 107 |
- } |
|
| 108 |
- |
|
| 109 |
- //관리자 페이지 로그인 후 사용자 페이지 접근시 로그아웃 처리_220421_이준호 |
|
| 110 |
- HttpSession session = request.getSession(); |
|
| 111 |
- LoginVO loginVO = (LoginVO) session.getAttribute("LoginVO");
|
|
| 112 |
- if( |
|
| 113 |
- !request.getServletPath().contains("/utl/wed/imageSrc.do")
|
|
| 114 |
- && !request.getServletPath().contains("/utl/wed/insertImage.do")
|
|
| 115 |
- && !request.getServletPath().contains("/cmm/fms/getImage2.do")
|
|
| 116 |
- ) {
|
|
| 117 |
- if(loginVO != null) {
|
|
| 118 |
- if("USR".equals(loginVO.getUserSe())) {
|
|
| 119 |
- request.getSession().invalidate(); |
|
| 120 |
- response.sendRedirect(request.getContextPath() + "/"); |
|
| 121 |
- return true; |
|
| 122 |
- } |
|
| 123 |
- } |
|
| 124 |
- } |
|
| 125 |
- |
|
| 23 |
+ |
|
| 24 |
+ //SameSite 설정하기 |
|
| 25 |
+ addSameSite(response, "None"); |
|
| 26 |
+ |
|
| 27 |
+ /** |
|
| 28 |
+ * URL 호출 전 넘어오는 파라미터 체크 |
|
| 29 |
+ * request로 넘어오는 모든 파라미터 데이터를 검사하여 XSS 문자가 포함되어 있으면 메인화면으로 튕김 |
|
| 30 |
+ * */ |
|
| 31 |
+ boolean returnSts1 = true; |
|
| 32 |
+ Enumeration e = request.getParameterNames(); |
|
| 33 |
+ while (e.hasMoreElements()) {
|
|
| 34 |
+ String name = (String) e.nextElement(); |
|
| 35 |
+ System.out.println("@@@@ " + name.toLowerCase());
|
|
| 36 |
+ if (!name.toLowerCase().contains("url")
|
|
| 37 |
+ && !name.toLowerCase().contains("pagetype")
|
|
| 38 |
+ && !name.toLowerCase().contains("searchsortcnd")
|
|
| 39 |
+ && !name.toLowerCase().contains("imgfilepath")
|
|
| 40 |
+ && !name.toLowerCase().contains("msgpreview")
|
|
| 41 |
+ && !name.toLowerCase().contains("smstxtarea")
|
|
| 42 |
+ && !name.toLowerCase().contains("smstxt")
|
|
| 43 |
+ && !name.toLowerCase().contains("rep1list")
|
|
| 44 |
+ && !name.toLowerCase().contains("rep2list")
|
|
| 45 |
+ && !name.toLowerCase().contains("rep3list")
|
|
| 46 |
+ && !name.toLowerCase().contains("rep4list")
|
|
| 47 |
+ && !name.toLowerCase().contains("namelist")
|
|
| 48 |
+ && !name.toLowerCase().contains("memolist")
|
|
| 49 |
+ && !name.toLowerCase().contains("info1list")
|
|
| 50 |
+ && !name.toLowerCase().contains("info2list")
|
|
| 51 |
+ && !name.toLowerCase().contains("info3list")
|
|
| 52 |
+ && !name.toLowerCase().contains("info4list")
|
|
| 53 |
+ && !name.toLowerCase().contains("nttcn")
|
|
| 54 |
+ && !name.toLowerCase().contains("ci")
|
|
| 55 |
+ && !name.toLowerCase().contains("certdi")
|
|
| 56 |
+ && !name.toLowerCase().contains("di")
|
|
| 57 |
+ && !name.toLowerCase().contains("mbldn")
|
|
| 58 |
+ && !name.toLowerCase().contains("mberid")
|
|
| 59 |
+ && !name.toLowerCase().contains("userid")
|
|
| 60 |
+ && !name.toLowerCase().contains("id_text")
|
|
| 61 |
+ && !name.toLowerCase().contains("mberemailadres")
|
|
| 62 |
+ && !name.toLowerCase().contains("recommendid")
|
|
| 63 |
+ && !name.toLowerCase().contains("mbernm")
|
|
| 64 |
+ && !name.toLowerCase().contains("varvallist")
|
|
| 65 |
+ && !name.toLowerCase().contains("templatecontent")
|
|
| 66 |
+ && !name.toLowerCase().contains("buttonvolist")
|
|
| 67 |
+ ) {
|
|
| 68 |
+ //파라미터 중에 URL 주소를 넘겨주는 부분이 있어서 해당 부분에것 select~, update~, delete~ 로 시작하는 주소경로가 있어서 제외처리를 하였음 |
|
| 69 |
+ String[] values = request.getParameterValues(name); |
|
| 70 |
+ |
|
| 71 |
+ //HTML 태그 관련 부분이 들어있으면 필터링 해주는 정규식 <> ~ </> 구문 찾아줌 |
|
| 72 |
+ //Pattern regex = Pattern.compile("<(/)?([a-zA-Z]*)(\\\\s[a-zA-Z]*=[^>]*)?(\\\\s)*(/)?>");
|
|
| 73 |
+ //23.7.18 이지우 - XSS 필터링을 위한 정규식 수정 |
|
| 74 |
+ Pattern regex = Pattern.compile("<[^ㄱ-ㅎㅏ-ㅣ가-힣<>]+>");
|
|
| 75 |
+ for (String value : values) {
|
|
| 76 |
+ |
|
| 77 |
+ //정규식과 동일한 패턴인지 비교해준다. |
|
| 78 |
+ Matcher matcher = regex.matcher(value); |
|
| 79 |
+ boolean rsltMatch = matcher.find(); |
|
| 80 |
+ |
|
| 81 |
+ //패턴이 일치하면 오류 발생 |
|
| 82 |
+ if (rsltMatch) {
|
|
| 83 |
+ |
|
| 84 |
+ returnSts1 = false; |
|
| 85 |
+ System.out.println("+++++++++++++++++++++++++++XSS Html 필터 처리 Filter Start::: ");
|
|
| 86 |
+ System.out.println("name=" + name + ", value=" + value);
|
|
| 87 |
+ System.out.println("+++++++++++++++++++++++++++XSS Html 필터 처리 Filter End::: ");
|
|
| 88 |
+ response.sendRedirect(request.getContextPath() + "/"); |
|
| 89 |
+ |
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ boolean returnSts = XssFilterUtil.cleanXSS(value); |
|
| 93 |
+ if (!returnSts) {//XSS 문자 체크 결과 false일 경우 메인화면으로 이동
|
|
| 94 |
+ returnSts1 = returnSts; |
|
| 95 |
+ System.out.println("+++++++++++++++++++++++++++XSS 필터 처리 Filter::: ");
|
|
| 96 |
+ System.out.println("name=" + name + ", value=" + value);
|
|
| 97 |
+ System.out.println("+++++++++++++++++++++++++++XSS 필터 처리 Filter End::: ");
|
|
| 98 |
+ response.sendRedirect(request.getContextPath() + "/"); |
|
| 99 |
+ } |
|
| 100 |
+ } |
|
| 101 |
+ } |
|
| 102 |
+ } |
|
| 103 |
+ |
|
| 104 |
+ if (!returnSts1) {//XSS 포함문자가 있는경우 메인화면으로 이동시킨다.
|
|
| 105 |
+ response.sendRedirect(request.getContextPath() + "/"); |
|
| 106 |
+ return true; |
|
| 107 |
+ } |
|
| 108 |
+ |
|
| 109 |
+ //관리자 페이지 로그인 후 사용자 페이지 접근시 로그아웃 처리_220421_이준호 |
|
| 110 |
+ HttpSession session = request.getSession(); |
|
| 111 |
+ LoginVO loginVO = (LoginVO) session.getAttribute("LoginVO");
|
|
| 112 |
+ if ( |
|
| 113 |
+ !request.getServletPath().contains("/utl/wed/imageSrc.do")
|
|
| 114 |
+ && !request.getServletPath().contains("/utl/wed/insertImage.do")
|
|
| 115 |
+ && !request.getServletPath().contains("/cmm/fms/getImage2.do")
|
|
| 116 |
+ && !request.getServletPath().contains("/cmm/fms/getImage.do")
|
|
| 117 |
+ ) {
|
|
| 118 |
+ if (loginVO != null) {
|
|
| 119 |
+ if ("USR".equals(loginVO.getUserSe())) {
|
|
| 120 |
+ request.getSession().invalidate(); |
|
| 121 |
+ response.sendRedirect(request.getContextPath() + "/"); |
|
| 122 |
+ return true; |
|
| 123 |
+ } |
|
| 124 |
+ } |
|
| 125 |
+ } |
|
| 126 |
+ |
|
| 126 | 127 |
return true; |
| 127 | 128 |
} |
| 128 |
- |
|
| 129 |
- /* |
|
| 130 |
- * view 화면으로 데이터가 넘어가기 이전에 실행 |
|
| 131 |
- * modelAndView 값을 체크할 수 있음 |
|
| 132 |
- * */ |
|
| 129 |
+ |
|
| 130 |
+ /* |
|
| 131 |
+ * view 화면으로 데이터가 넘어가기 이전에 실행 |
|
| 132 |
+ * modelAndView 값을 체크할 수 있음 |
|
| 133 |
+ * */ |
|
| 133 | 134 |
@Override |
| 134 | 135 |
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
|
| 135 | 136 |
super.postHandle(request, response, handler, modelAndView); |
| 136 | 137 |
} |
| 137 |
- |
|
| 138 |
+ |
|
| 138 | 139 |
/* |
| 139 |
- * |
|
| 140 |
+ * |
|
| 140 | 141 |
* view에서 모든 처리를 완료한 후에 실행 |
| 141 | 142 |
* */ |
| 142 | 143 |
@Override |
| 143 | 144 |
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
|
| 144 | 145 |
super.afterCompletion(request, response, handler, ex); |
| 145 | 146 |
} |
| 146 |
- |
|
| 147 |
+ |
|
| 147 | 148 |
private void addSameSite(HttpServletResponse response, String sameSite) {
|
| 148 |
- |
|
| 149 |
+ |
|
| 149 | 150 |
Collection<String> headers = response.getHeaders(HttpHeaders.SET_COOKIE); |
| 150 | 151 |
boolean firstHeader = true; |
| 151 | 152 |
for (String header : headers) { // there can be multiple Set-Cookie attributes
|
... | ... | @@ -156,7 +157,7 @@ |
| 156 | 157 |
} |
| 157 | 158 |
response.addHeader(HttpHeaders.SET_COOKIE, String.format("%s; Secure; %s", header, "SameSite=" + sameSite));
|
| 158 | 159 |
} |
| 159 |
- |
|
| 160 |
+ |
|
| 160 | 161 |
} |
| 161 |
- |
|
| 162 |
+ |
|
| 162 | 163 |
} |
--- src/main/java/itn/com/cmm/web/EgovImageProcessController.java
+++ src/main/java/itn/com/cmm/web/EgovImageProcessController.java
... | ... | @@ -7,6 +7,7 @@ |
| 7 | 7 |
import java.util.Map; |
| 8 | 8 |
|
| 9 | 9 |
import javax.annotation.Resource; |
| 10 |
+import javax.servlet.ServletOutputStream; |
|
| 10 | 11 |
import javax.servlet.http.HttpServlet; |
| 11 | 12 |
import javax.servlet.http.HttpServletResponse; |
| 12 | 13 |
|
... | ... | @@ -60,99 +61,79 @@ |
| 60 | 61 |
* @param response |
| 61 | 62 |
* @throws Exception |
| 62 | 63 |
*/ |
| 63 |
- @SuppressWarnings("resource")
|
|
| 64 | 64 |
@RequestMapping("/cmm/fms/getImage.do")
|
| 65 | 65 |
public void getImageInf(SessionVO sessionVO, ModelMap model, @RequestParam Map<String, Object> commandMap, HttpServletResponse response) throws Exception {
|
| 66 | 66 |
|
| 67 | 67 |
String atchFileId = (String) commandMap.get("atchFileId");
|
| 68 | 68 |
String fileSn = (String) commandMap.get("fileSn");
|
| 69 | 69 |
String isThumbFile = (String) commandMap.get("isThumbFile");
|
| 70 |
- |
|
| 71 |
- FileVO vo = new FileVO(); |
|
| 72 |
- |
|
| 73 |
- vo.setAtchFileId(atchFileId); |
|
| 74 |
- vo.setFileSn(fileSn); |
|
| 75 |
- |
|
| 76 |
- //------------------------------------------------------------ |
|
| 77 |
- // fileSn이 없는 경우 마지막 파일 참조 |
|
| 78 |
- //------------------------------------------------------------ |
|
| 79 |
- if (fileSn == null || fileSn.equals("")) {
|
|
| 80 |
- int newMaxFileSN = fileService.getMaxFileSN(vo); |
|
| 81 |
- vo.setFileSn(Integer.toString(newMaxFileSN - 1)); |
|
| 82 |
- } |
|
| 83 |
- //------------------------------------------------------------ |
|
| 84 |
- FileVO fvo = fileService.selectFileInf(vo); |
|
| 85 |
- |
|
| 86 |
- String fileNm = fvo.getStreFileNm(); |
|
| 87 |
- // 섬네일 이미지 경우 |
|
| 88 |
- if (isThumbFile != null && ("thumbFile").equals(isThumbFile) && fvo.getThumbFileNm() != null) {
|
|
| 89 |
- fileNm = fvo.getThumbFileNm(); |
|
| 90 |
- } |
|
| 91 |
- |
|
| 92 |
- File file = new File(fvo.getFileStreCours(), fileNm); |
|
| 93 |
- |
|
| 94 |
- FileInputStream fis = null; |
|
| 95 | 70 |
try {
|
| 96 |
- new FileInputStream(file); |
|
| 97 |
- }catch(Exception e) {}
|
|
| 98 |
- |
|
| 99 |
- BufferedInputStream in = null; |
|
| 100 |
- ByteArrayOutputStream bStream = null; |
|
| 101 |
- try {
|
|
| 102 |
- fis = new FileInputStream(file); |
|
| 103 |
- in = new BufferedInputStream(fis); |
|
| 104 |
- bStream = new ByteArrayOutputStream(); |
|
| 105 |
- int imgByte; |
|
| 106 |
- /*while ((imgByte = in.read()) != -1) {
|
|
| 107 |
- bStream.write(imgByte); |
|
| 108 |
- }*/ |
|
| 109 |
- |
|
| 110 |
- byte[] outputByte=new byte[104096]; |
|
| 111 |
- while ((imgByte =in.read(outputByte, 0, 4096 )) > 0 ) {
|
|
| 112 |
- bStream.write(outputByte,0,imgByte); |
|
| 71 |
+ if (atchFileId == null || atchFileId.trim().isEmpty()) {
|
|
| 72 |
+ response.setStatus(HttpServletResponse.SC_BAD_REQUEST); |
|
| 73 |
+ return; |
|
| 113 | 74 |
} |
| 114 |
- String type = ""; |
|
| 115 |
- if (fvo.getFileExtsn() != null && !"".equals(fvo.getFileExtsn())) {
|
|
| 116 |
- if ("jpg".equals(fvo.getFileExtsn().toLowerCase())) {
|
|
| 117 |
- type = "image/jpeg"; |
|
| 118 |
- } else {
|
|
| 119 |
- type = "image/" + fvo.getFileExtsn().toLowerCase(); |
|
| 75 |
+ |
|
| 76 |
+ FileVO vo = new FileVO(); |
|
| 77 |
+ vo.setAtchFileId(atchFileId); |
|
| 78 |
+ vo.setFileSn(fileSn); |
|
| 79 |
+ |
|
| 80 |
+ //------------------------------------------------------------ |
|
| 81 |
+ // fileSn이 없는 경우 마지막 파일 참조 |
|
| 82 |
+ //------------------------------------------------------------ |
|
| 83 |
+ if (fileSn == null || fileSn.trim().isEmpty()) {
|
|
| 84 |
+ int newMaxFileSN = fileService.getMaxFileSN(vo); |
|
| 85 |
+ if (newMaxFileSN <= 0) {
|
|
| 86 |
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND); |
|
| 87 |
+ return; |
|
| 120 | 88 |
} |
| 121 |
- //type = "image/" + fvo.getFileExtsn().toLowerCase(); |
|
| 122 |
- |
|
| 123 |
- } else {
|
|
| 124 |
- LOGGER.debug("Image fileType is null.");
|
|
| 89 |
+ vo.setFileSn(Integer.toString(newMaxFileSN - 1)); |
|
| 125 | 90 |
} |
| 126 | 91 |
|
| 127 |
- response.setHeader("Content-Type", type);
|
|
| 128 |
- response.setContentLength(bStream.size()); |
|
| 129 |
- bStream.writeTo(response.getOutputStream()); |
|
| 130 |
- response.getOutputStream().flush(); |
|
| 131 |
- response.getOutputStream().close(); |
|
| 92 |
+ FileVO fvo = fileService.selectFileInf(vo); |
|
| 93 |
+ if (fvo == null) {
|
|
| 94 |
+ LOGGER.warn("이미지 파일 정보 없음: atchFileId={}, fileSn={}", atchFileId, vo.getFileSn());
|
|
| 95 |
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND); |
|
| 96 |
+ return; |
|
| 97 |
+ } |
|
| 98 |
+ |
|
| 99 |
+ String fileNm = fvo.getStreFileNm(); |
|
| 100 |
+ if ("thumbFile".equals(isThumbFile) && fvo.getThumbFileNm() != null
|
|
| 101 |
+ && !fvo.getThumbFileNm().trim().isEmpty()) {
|
|
| 102 |
+ fileNm = fvo.getThumbFileNm(); |
|
| 103 |
+ } |
|
| 104 |
+ |
|
| 105 |
+ File file = new File(fvo.getFileStreCours(), fileNm); |
|
| 106 |
+ if (!file.isFile() || !file.canRead()) {
|
|
| 107 |
+ LOGGER.warn("이미지 파일 없음: atchFileId={}, fileSn={}, path={}",
|
|
| 108 |
+ atchFileId, vo.getFileSn(), file.getAbsolutePath()); |
|
| 109 |
+ response.setStatus(HttpServletResponse.SC_NOT_FOUND); |
|
| 110 |
+ return; |
|
| 111 |
+ } |
|
| 112 |
+ |
|
| 113 |
+ String type = null; |
|
| 114 |
+ if (fvo.getFileExtsn() != null && !fvo.getFileExtsn().trim().isEmpty()) {
|
|
| 115 |
+ String extension = fvo.getFileExtsn().toLowerCase(); |
|
| 116 |
+ type = "jpg".equals(extension) ? "image/jpeg" : "image/" + extension; |
|
| 117 |
+ } |
|
| 118 |
+ |
|
| 119 |
+ response.setContentType(type != null ? type : "application/octet-stream"); |
|
| 120 |
+ response.setContentLengthLong(file.length()); |
|
| 121 |
+ |
|
| 122 |
+ try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(file))) {
|
|
| 123 |
+ ServletOutputStream out = response.getOutputStream(); |
|
| 124 |
+ byte[] buffer = new byte[8192]; |
|
| 125 |
+ int length; |
|
| 126 |
+ while ((length = in.read(buffer)) != -1) {
|
|
| 127 |
+ out.write(buffer, 0, length); |
|
| 128 |
+ } |
|
| 129 |
+ out.flush(); |
|
| 130 |
+ } |
|
| 132 | 131 |
|
| 133 | 132 |
} catch (Exception e) {
|
| 134 |
- LOGGER.debug("{}", e);
|
|
| 135 |
- } finally {
|
|
| 136 |
- if (bStream != null) {
|
|
| 137 |
- try {
|
|
| 138 |
- bStream.close(); |
|
| 139 |
- } catch (Exception est) {
|
|
| 140 |
- LOGGER.debug("IGNORED: {}", est.getMessage());
|
|
| 141 |
- } |
|
| 142 |
- } |
|
| 143 |
- if (in != null) {
|
|
| 144 |
- try {
|
|
| 145 |
- in.close(); |
|
| 146 |
- } catch (Exception ei) {
|
|
| 147 |
- LOGGER.debug("IGNORED: {}", ei.getMessage());
|
|
| 148 |
- } |
|
| 149 |
- } |
|
| 150 |
- if (fis != null) {
|
|
| 151 |
- try {
|
|
| 152 |
- fis.close(); |
|
| 153 |
- } catch (Exception efis) {
|
|
| 154 |
- LOGGER.debug("IGNORED: {}", efis.getMessage());
|
|
| 155 |
- } |
|
| 133 |
+ LOGGER.error("이미지 조회 실패: atchFileId={}, fileSn={}", atchFileId, fileSn, e);
|
|
| 134 |
+ if (!response.isCommitted()) {
|
|
| 135 |
+ response.reset(); |
|
| 136 |
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); |
|
| 156 | 137 |
} |
| 157 | 138 |
} |
| 158 | 139 |
} |
Add a comment
Delete comment
Once you delete this comment, you won't be able to recover it. Are you sure you want to delete this comment?