mardi 8 juin 2021

How can I use MultiPartConfig annotations If implement Front-Controller pattern?

I have front controller that recieves all request

 @WebServlet(name = "FrontController", value = "/pages/*")
    public class FrontController extends HttpServlet {
        @Override
        protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            ServletContext context = getServletContext();
            String error = (String)context.getAttribute("Error");
            if(error!=null){
                req.getRequestDispatcher("/WEB-INF/view/error.jsp?errorMessage="+error);
            }
            try {
                View view = new View(req, resp);
                Action action = ActionFactory.getInstance().getAction(req);
                action.execute(view);
                view.navigate();
            } catch (Exception e) {
                req.getRequestDispatcher("/WEB-INF/view/error.jsp?errorMessage="+e.getMessage());
            }
        }
    }

And I have profile.jsp page that can send async request by axios to servlet on url /pages/user/setImage

profile.jsp :

<div id="q-app">
    <div>
        <%@include file="../fichiers/headerHome.jsp"%>
    </div>
    <div class="q-pa-md row justify-center">
        <div class="col-4">
            <q-card  class="q-ma-md col">
                <q-card-section class="text-center text-h5 q-pt-none">
                    <fmt:localeValue key="profileInfo"/>
                </q-card-section>
            </q-card>
            <input type="file" id="file"
                   ref="file" accept=".jpg, .jpeg, .png"
                   style="display:none"
                   @change="handleFileUpload()"/>
            <q-btn style="height:500px;" class="q-ma-md col" @click="tclick">
                <c:if test="${sessionScope.profileImage==null}">
                    <q-avatar size="500px"  icon="portrait"></q-avatar>
                </c:if>
                <c:if test="${sessionScope.profileImage!=null}">
                    <q-img  height="100%" width="100%" :src="imageSrc">
                    </q-img>
                </c:if>
            </q-btn>
            <q-card  class="q-ma-md col">
                <q-card-section class="text-center bg-primary text-white">
                   <fmt:localeValue key="dialogFirstName"/>
                </q-card-section>
                <q-separator></q-separator>
                <q-card-section class="text-center text-h5 q-pt-none">
                   ${requestScope.profileFirstName}
                </q-card-section>
                <q-card-section class="text-center bg-primary text-white">
                    <fmt:localeValue key="dialogSurName"/>
                </q-card-section>
                <q-separator></q-separator>
                <q-card-section class="text-center text-h5 q-pt-none">
                    ${requestScope.profileSurName}
                </q-card-section>
                <q-card-section class="text-center bg-primary text-white">
                    <fmt:localeValue key="profileRegistrationDate"/>
                </q-card-section>
                <q-separator></q-separator>
                <q-card-section class="text-center text-h5 q-pt-none">
                    ${requestScope.profileRegistrationDate}
                </q-card-section>
            </q-card>
            <q-btn class="q-mt-md" style="width:100%;" @click="submitFile()" color="primary" label="changeProfilePicture"></q-btn>
        </div>
    </div>
</div>
</body>
<script>
    new Vue({
        el: '#q-app',
        data () {
            return {
                file: '',
                imageSrc:'${sessionScope.profileImage}',
                Eng:'',
                Ua:'',
                Ru:''

            }
        },
        methods:{
            tclick(){
                this.$refs.file.click()
            },
            handleFileUpload(){
                this.file = this.$refs.file.files[0];
            },
            submitFile(){
                let formData = new FormData();
                formData.append('file', this.file);
                axios.post( "${pageContext.request.contextPath}"+"/pages/user/setImage",
                    formData,
                    {
                        headers: {
                            'Content-Type': 'multipart/form-data'
                        }
                    }
                ).then(response => {
                    this.$q.notify({
                        type: 'positive',
                        message: response.data,
                        position:'center',
                        icon: 'check'
                    });
                    const reader = new FileReader();
                    reader.readAsDataURL(this.file);
                    reader.onload = () => {
                        this.image = reader.result;
                    };

                }).catch(error => {
                    console.log(error);
                })
            }
}
}
}
});

And front-controller get request and delegate It to action

SetImage Action : 
public class SetImageAction implements Action{

    private String uploadDir = "userProfileImages";
    @Override
    public void execute(View view) throws Exception {
        HttpServletRequest request = view.getRequest();
        String uploadPath = ImageUtil.getFolderStoreImage(request.getServletContext().getRealPath(File.separator),uploadDir);
        String fileName;
        DAOFactory dao =(MySQLDAOFactory)request.getServletContext().getAttribute("MySQLFactory");
        ProfileDao profileDao = dao.getProfileDao();
        UserDao userDao = dao.getUserDao();
        TaxiServiceProfile taxiServiceProfile = new TaxiServiceProfile(profileDao);
        TaxiServiceUser taxiServiceUser = new TaxiServiceUser(userDao);
        HttpSession session = request.getSession();
        ObjectMapper mapper = new ObjectMapper();
        File fileUploadDir = new File(uploadPath);
        if (!fileUploadDir.exists()) {
            fileUploadDir.mkdir();
        }
        Part part = request.getPart("file");
        fileName = part.getSubmittedFileName();
        User user = taxiServiceUser.findUser((String) session.getAttribute("Login"));
        String imageLocation = uploadPath + File.separator + fileName;
        part.write(imageLocation);
        taxiServiceProfile.updateProfile(user.getUserId(),imageLocation);
        session.setAttribute("profileImage",imageLocation);
        String message = "Your image has been successfully loaded";
        request.setAttribute("setImageResult",mapper.writeValueAsString(message));
        view.setView(request.getPathInfo());
    }
}

But It doesn't work because front-controller doesn't have annotation @MultipartConfig And I get this message : Unable to process parts as no multi-part configuration has been provided

I can solve It to set annotation but will it mess up the design? Also, is there any other way to solve this problem?

Aucun commentaire:

Enregistrer un commentaire