Ext + Struts2 파일 업로드 상세 정보

7794 단어 ext
얼마 전 프로젝트에서 파일 업로드 기능을 실현해야 했는데 앞뒤로 나를 포함한 세 사람이 바꿔서 했는데 아주 오랜 시간이 걸려서 잘 됐어요. 사소한 문제로 인해 시간이 오래 걸렸어요.손이 뜨거워지는 틈을 타서 써서 여러분께 나누어 드리겠습니다. 본문을 찾으신 분들은 시행착오를 줄일 수 있기를 바랍니다.
프로젝트에 사용된 기술은 ExtJs3.3과 SSH 등이며 파일 업로드와 관련된 기술은 주로 Ext와 Struts2이다.
처음에는 한 동료가 만들었습니다. Ext 예시 패키지의 FileUploadField를 사용했습니다. 페이지에서 두 개의 파일을 인용해야 합니다./ext/examples/ux/fileuploadfield/css/fileuploadfield.css 및/ext/examples/ux/fileuploadfield/FileUploadField.js.
쓸데없는 말은 그만두고 코드를 직접 붙이면 중간에 여러 가지 곡절의 과정이 생략된다.파일에 업로드된 탄창은 Windows로 FormPanel이 내장되어 있습니다.

var fp = new Ext.FormPanel( {
       renderTo : Ext.getBody(),
       fileUpload : true,
       width : 523,
       frame : true,
       autoHeight : true,
       bodyStyle : 'padding: 10px 10px 0 10px;',
       labelWidth : 50,
       defaults : {
           anchor : '95%',
           allowBlank : false,
           msgTarget : 'side'
       },
         items : [
                            new Ext.form.FileUploadField( {
              buttonText: ' ...',
              emptyText: ' xls ',
              name : 'xlsFile',
              width : 500,
              buttonCfg: {
                  width: 40,
                  iconCls: 'upload-icon'
              }
           }) 
    ],
        buttons : [ {
           text : ' ',
           handler : function() {
              if (fp.getForm().isValid()) {
                  fp.getForm().submit( {
                     method : 'post',
                     url :'uploadEmployee.action',//  action
                     waitMsg : ' , ...',
                      waitTitle:' ',
                     success :function(fp,action){
                         Ext.Msg.alert('Success', 'The value of success is: "'+action.result.success+'" on the server');
                         excelWindow.destroy();
                     },
                     failure : function(fp, action) {
                          var msg = action.response.responseText;
                            var obj = Ext.decode( msg );
                            Ext.Msg.alert(" ", "Sorry, , :" + obj.message);
                            excelWindow.destroy();
                     }
              });
                            }
                   }
         }]
});
 
var excelWindow = new Ext.Window( {
       renderTo : Ext.getBody(),
       closeAction : "hide",
       plain : true,
       width : 540,
       title : " ",
       modal : true,
       items:[fp]
    });
excelWindow.show();

그리고 백그라운드에서 처리된 액션에서 어떤 값을 되돌려주든지 상관없습니다. 성공, NONE, 심지어 사용자 정의 문자열도 가능합니다.여기서 말하는'귀환'은 액션 안의 처리 함수 자체의 귀환을 가리킨다. 나는 네가 알고 있다고 믿는다.액션에서 프론트 데스크톱으로 되돌아오는 json 데이터에 {success:false} 이 값이 포함되지 않으면success:true도 생략하고 쓰지 않아도 됩니다. Ext는 파일 업로드 작업이 성공했다고 생각합니다.submit 방법에서success 속성이 정의한 리셋 함수를 실행할 것입니다.
struts 구성 파일의 일부는 다음과 같습니다.

<action name="uploadEmployee" class="uploadEmployeeService">
       <interceptor-ref name="fileUpload">
              <param name="maximumSize">10485760</param>
              <param name="allowedTypes">application/vnd.ms-excel</param>
       </interceptor-ref>
       <interceptor-ref name="defaultStack"/>
       <result name="success" type="json">
              <param name="contentType">text/html</param>
        </result>
        <result name="test1">/employee/jsp/test.jsp
              <param name="contentType">text/html</param>
        </result>
</action>

ContentType은 text/html 형식으로 설정해야 합니다. 그렇지 않으면 브라우저가 정확하게 처리하지 못해 서버 측의 응답을 파일 알림으로 사용자에게 다운로드할 수 있습니다.프론트 데스크에 데이터를 정확하게 응답하려면 여러 가지 방법이 있다(필자는 현재 세 가지를 발견했다).
1. action이 json 형식으로 되돌아오는 데이터를 직접 지정할 수 있습니다. 위와 같이resultname="success"의 되돌아오는 형식은 다음과 같습니다.만약 이런 방식을 사용한다면 상응하는 액션 클래스에 세 가지 속성을 포함하는 것이 가장 좋다. 그것이 바로success,filename,msg이다.그 중에서success의 유형은 String일 수도 있고boolean일 수도 있으며 다른 두 속성은 String 유형일 수도 있다.만약에 Action의 방법이 되돌아올 때success의 값이false라면 파일 업로드 실패를 나타낼 수 있고 msg 속성은 파일 업로드 실패의 원인을 가리킬 수 있다.filename은 파일의 이름을 저장하는 데 사용할 수 있습니다.
어떤 방식이든 콘텐츠 type의 형식은 반드시 text/html로 설정해야 합니다. 그렇지 않으면 브라우저가 서버 측의 응답을 파일로 삼아 다운로드할 수 있습니다.
2. 텍스트 파일에 json 형식의 문자열을 포함하여 서버 측이 클라이언트에 대한 반응으로 사용할 수 있다.위의 result name = "test1"의 설정과 같습니다.여기서 Action의 반환 값이'test1'일 때 클라이언트에게test를 반환합니다.jsp 페이지에 포함된 내용입니다. 이 페이지에는 {success:true} 라는 문장만 썼을 수도 있습니다. 서버 측이 클라이언트에게 이 json 응답을 되돌려 준 것과 같습니다.
그러나 이런 방법은 비교적 죽을 수도 있다. 첫 번째 방법보다 유연하고 편리하지 않다. 특히 파일 업로드(또는 업로드 후의 해석)가 실패한 상황을 고려해야 하기 때문에 오류 정보는 되돌아오기가 쉽지 않다.
3. Action에서 HttpServletResponse를 사용하여 클라이언트에 직접 응답할 수 있습니다.예를 들어 클라이언트 응답을 작성하는 함수는 다음과 같습니다.

privatevoid sendMsg(String content) throws IOException{
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html");
        response.getWriter().write(content);
        response.getWriter().flush();
        response.getWriter().notify();
}

이렇게 하면 클라이언트에게 되돌려줄 json 내용을 {success:true}와 같은 표준 형식으로sendMsg 함수에 전달하면 됩니다.필자는 여기에서 Writer의flush와notify 함수를 호출하면sendMsg 함수가 보낸 데이터가 클라이언트에게 바로 전송될 것을 건의합니다.그래서 당신의 Action의 반환값은 마음대로 할 수 있습니다. 입력이나 ERROR도 상관없습니다.첫 번째 방법과 마찬가지로 유연하지만 첫 번째 방법보다 편리하지 않다.
너무 쉽죠?사실 첫 번째 동료가 했을 때 잘 할 뻔했다. 주요한 문제는 바로 그가success 리셋 함수에서 예시 프로그램의 사용자 정의 함수 msg를 사용했는데 msg 함수에 정의된 코드를 도입하지 않았다. 결과적으로 파일이 성공적으로 업로드되어도success 리셋 함수에 실행될 때 반드시 오류가 발생하여 업로드 대화상자를 정상적으로 닫을 수 없다는 것이다.
또 다른 이유는 프로젝트에'반복 로그인'을 판단하는 전역 함수가 있는데 Ajax가 서버에서 요청한response를 사용하여response를 사용했기 때문이다.getResponseHeader() 함수를 판단합니다.파일 업로드가 끝난 후, 여기는 항상 오류를 보고합니다. response에 getResponseHeader () 방법이 없습니다.처음에 제가 했을 때 경험이 없어서 이 문제를 별로 신경 쓰지 않았어요. 이게 파일 업로드와 무관하다고 생각하고 파일 업로드 자체에 집중했는데 시간이 많이 지체됐어요.나중에 API 문서를 자세히 볼 때, FormPanel의 기본 클래스, 클래스 Ext.form.BasicForm의 설명에서는 다음과 같은 문구가 있습니다.
The response text is retrieved from the document, and a fake XMLHttpRequest object is created containing aresponseText property in order to conform to the requirements of event handlers and callbacks.
즉, Ext가 FormPanel로 진행된 파일을 업로드할 때 Ajax가 요청한 것은 위조 응답 (fake XMLHttpRequest) 으로 일반적인 response로 사용할 수 없습니다.이 전역 함수를 수정하여 파일에 업로드된response에 대해 getResponseHeader () 함수를 호출하는 판단을 건너뛰었습니다.문제가 마침내 해결되었다!
피의 교훈!원래 모든 Javascript 파일에서 오류 문법 오류가 발생하면 전체 페이지의 모든 js의 실행에 영향을 줄 수 있습니다!그러나 이 전체 과정에서 약간의 Ext에 대해 깊은 인식을 가지게 되었다. 더 이상 회사에 막 들어왔을 때가 아니라 임무를 가지고 기존의 코드를 직접 참조하여 간단하게 증가하고 수정했다.Ajax도 알고 디버깅 도구 사용도 배웠어요.
Ext가 아직 더위를 막지 않았는데 저는 프로젝트의 필요에 따라 arcgis를 돌렸습니다. 플렉스 등을 배워야 할 것 같습니다. 학교 기말도 다가오고 배울 것이 너무 많아서... 쓸데없는 소리 하지 마세요~
후기: 프로젝트의 모든 aax 요청이 어떤 방법을 실행하는데 getResponseHeader () 가 사용된다면 파일에 올라온 aax 요청의 판단을 어떻게 건너뛰나요?예를 들어 저희 프로젝트에서 Ajax가 요청한 데이터는 모두 JSON 형식입니다. 제가 사용하는 방법은response가 JSON 데이터라면 그 안에 우리가 올린 파일이 있는지 분석하는 것입니다. (이름을 찾으면 됩니다.) 그러면 이 aax 요청이 파일에 업로드된 것인지 판단하고 건너뛰었는지 여부를 결정할 수 있습니다.

var t = response.responseText;
if(t.charAt(0)=="{"){
       if( Ext.decode(t).xlsFileFileName ){
              return;
       }
}

좋은 웹페이지 즐겨찾기