首页 > 解决方案 > 如果实现 Front-Controller 模式,如何使用 MultiPartConfig 注释?

问题描述

我有接收所有请求的前端控制器

 @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());
            }
        }
    }

我有 profile.jsp 页面,可以通过 axios 向 url 上的 servlet 发送异步请求/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);
                })
            }
}
}
}
});

前端控制器获取请求并将其委托给操作

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());
    }
}

但它不起作用,因为前端控制器没有注释@MultipartConfig 我收到这条消息:

Unable to process parts as no multi-part configuration has been provided

我可以解决它来设置注释,但它会弄乱设计吗?另外,有没有其他方法可以解决这个问题?

标签: javaservletsdesign-patternsmultipartform-datafront-controller

解决方案


推荐阅读