0

Upload a file through spring forms returning HTTP Status 405 - Request method 'POST' not supported, Spring Security is Enabled

Java Based Configuration

    public class SecurityWebApplicationInitializer extends AbstractSecurityWebApplicationInitializer {

        @Override
        protected void beforeSpringSecurityFilterChain(ServletContext servletContext) {
            insertFilters(servletContext, new MultipartFilter());
        }

    }

Model

    @Entity
    @Table(name="alumni")
    public class Alumni implements Serializable{

        private static final long serialVersionUID = 1L;

        @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer id;

        @NotEmpty
        @Column(name="studentName", nullable=false)
        private String studentName;

        @NotEmpty
        @Column(name="program", nullable=false)
        private String program;

        @Transient
        private MultipartFile file;

        @Column(name="content")
        @Lob
        private Blob content;

        @Column(name="contentType", nullable=false)
        private String contentType;

        @Column(name="fileName", nullable=false)
        private String fileName;


        public Integer getId() {
            return id;
        }

        public void setId(Integer id) {
            this.id = id;
        }

        public String getStudentName() {
            return studentName;
        }

        public void setStudentName(String studentName) {
            this.studentName = studentName;
        }

        public String getProgram() {
            return program;
        }

        public void setProgram(String program) {
            this.program = program;
        }

        public Blob getContent() {
            return content;
        }

        public void setContent(Blob content) {
            this.content = content;
        }

        public String getContentType() {
            return contentType;
        }

        public void setContentType(String contentType) {
            this.contentType = contentType;
        }

        public String getFileName() {
            return fileName;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        public MultipartFile getFile() {
            return file;
        }

        public void setFile(MultipartFile file) {
            this.file = file;
        }

    }

Controller

    @RequestMapping(value={"/alumni"}, method=RequestMethod.POST)
    public String saveAlumni(@Valid Alumni alumni, BindingResult result, ModelMap model) {
        System.out.println("Alumni : "+alumni);
        if (result.hasErrors()) {
            model.addAttribute("errors", result.getAllErrors());
            return "alumni_u";
        } else {

            Verification verification = verificationService.getByTypeAndVerificationOn(VerificationType.EMAIL.getVerificationType(), alumni.getEmail());

            if(verification!=null && verification.getCode().equals(alumni.getEmailVerificationCode())){
                if(alumni.getFile()!=null){
                    try{
                        if(Arrays.asList(imageArray).contains(alumni.getFile().getContentType())){
                            alumni.setContent(new SerialBlob(alumni.getFile().getBytes()));
                            alumni.setContentType(alumni.getFile().getContentType());
                            alumni.setFileName(alumni.getFile().getOriginalFilename());
                            alumniService.save(alumni);
                        }else{
                            model.addAttribute("errors",  messageSource.getMessage("NotAllowed.alumni.image.format", null, null));
                            return "alumni_u";
                        }
                    }catch(Exception e){
                        logger.error(messageSource.getMessage("Error.alumni.file.blob", null, null));
                        e.printStackTrace();
                        model.addAttribute("errors", messageSource.getMessage("Error.alumni.file.blob", null, null));
                        return "alumni_u";
                    }
                }else{
                    alumniService.save(alumni);
                }
            }else{
                model.addAttribute("errors", messageSource.getMessage("Invalid.alumni.verificationCode.email", new Object[] {alumni.getEmail()}, null));
                return "alumni_u";
            }

            model.addAttribute("success", messageSource.getMessage("success.alumni.form.submition", null, null));
            return "alumniSuccess_u";
        }
    }

Form

    <form:form method="POST" modelAttribute="alumni" enctype="multipart/form-data" >

        <form:errors path="*" class="has-error" />
        <form:input type="hidden" path="id" id="id" />

       <ul>
         <li class="alumni-leftinput clear">
            <label>Name* :</label>
            <form:input type="text" path="studentName" id="studentName" onkeypress="return keyRestrict(event, 'char');"/>
            <div class="has-error">
                <form:errors path="studentName" class="help-inline"/>
            </div>
         </li>
         <li class="alumni-leftinput clear">
            <label>Department/Program* :</label>
            <form:select path="program" class="form-control input-sm" onchange="getAlumniCourse();">
                <form:option value="" label="--- Select ---" />
                <form:option value="Under Graduate" label="Under Graduate - UG"/>
                <form:option value="Post Graduate" label="Post Graduate - PG"/>
            </form:select>
            <div class="has-error">
                <form:errors path="program" class="help-inline"/>
            </div>
         </li>
         <li class="full-width clear">
            <label>Recent color photograph (Image dimensions 2" x 2") :</label>
            <form:input type="file" path="file" id="file" />
            <span>Upload Bitmap / jpeg / gif / png formats only. Size below 2MB</span>
         </li>
         <li class="clear">
            <button type="submit" class="dt-sc-button noborder" value="Submit">Submit</button>
         </li>
       </ul>

Getting CSRF Value from Spring form

     <input type="hidden" name="_csrf" value="7ba6b5a7-7fed-4bb6-b54e-a781576e85e3">

Application Configuration

    @Bean
    public CommonsMultipartResolver multipartResolver() throws IOException{
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setDefaultEncoding("utf-8");
        resolver.setMaxUploadSizePerFile(5242880);//5MB         
        return resolver;
    }

Request Header

POST /urce/alumni HTTP/1.1

Host: localhost:8080

Connection: keep-alive

Content-Length: 96286

Cache-Control: max-age=0

Origin: http://localhost:8080

Upgrade-Insecure-Requests: 1

Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryrAL3hxUGtppolJFd

User-Agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,/;q=0.8

Referer: http://localhost:8080/urce/alumni

Accept-Encoding: gzip, deflate, br

Accept-Language: en-US,en;q=0.9

Cookie: JSESSIONID=1ED3DB210F38EC734E99CE420E16042B; _ga=GA1.1.1771599779.1532604925; _gid=GA1.1.1755993342.1534396304; _gat=1

DNT: 1


Response Header

HTTP/1.1 405 Method Not Allowed

Server: Apache-Coyote/1.1

X-Content-Type-Options: nosniff

X-XSS-Protection: 1; mode=block

Cache-Control: no-cache, no-store, max-age=0, must-revalidate

Pragma: no-cache

Expires: 0

X-Frame-Options: DENY

Allow: GET

Content-Type: text/html;charset=ISO-8859-1

Content-Language: en

Content-Length: 1047

Date: Fri, 17 Aug 2018 08:49:28 GMT


Solution

By Specifying the @Bean(name="filterMultipartResolver") annotation on top of public CommonsMultipartResolver getMultipartResolver() method in Application Configuratuin which extends WebMvcConfigurerAdapter resoved my Issue

Make sure that the bean is name called filterMultipartResolver (name="filterMultipartResolver") as any other bean name is not picked up by MultipartFilter.

My initial configuration was not working because this bean was named as name="multipartResolver" and I also tested by removing name in @Bean annotation

I followed the solution provided in this link

    @Bean(name="filterMultipartResolver")
    public CommonsMultipartResolver getMultipartResolver() throws IOException{
        CommonsMultipartResolver resolver = new CommonsMultipartResolver();
        resolver.setDefaultEncoding("utf-8");
        resolver.setMaxUploadSizePerFile(5242880);//5MB         
        return resolver;
    }

0 Answers0