Как загрузить закодированное изображение base64 на сервер с помощью spring

#spring

#spring

Вопрос:

Я пишу веб-сервис с использованием spring.
Эта служба принимает изображение в кодировке base64 в качестве строкового параметра.
Я хочу декодировать эту строку в изображение и загрузить на сервер.

 @RequestMapping(value="/uploadImage",method = RequestMethod.POST)
public @ResponseBody String uploadImage(@RequestParam("encodedImage") String encodedImage)
{
    byte[] imageByte= Base64.decodeBase64(encodedImage);
    return null;
}
  

Ответ №1:

Приведенный ниже код используется для декодирования строки, которая кодируется с помощью base 64 и используется для загрузки изображения на сервер.

Для меня это работает нормально..

 @RequestMapping(value="/uploadImage2",method = RequestMethod.POST)
    public @ResponseBody String uploadImage2(@RequestParam("imageValue") String imageValue,HttpServletRequest request)
    {
        try
        {
            //This will decode the String which is encoded by using Base64 class
            byte[] imageByte=Base64.decodeBase64(imageValue);

            String directory=servletContext.getRealPath("/") "images/sample.jpg";

            new FileOutputStream(directory).write(imageByte);
            return "success ";
        }
        catch(Exception e)
        {
            return "error = " e;
        }

    }
  

Комментарии:

1. Мне пришлось разделить значение imageValue на первую запятую и взять оставшуюся часть, поскольку я отправил все изображение, включая «заголовок». Кроме того, это Base64.GetDecoder().decode(), если вы используете java.util.Base64. Надеюсь, эти два лакомых кусочка кому-нибудь помогут.

Ответ №2:

Используйте Java Base64.Decoder для декодирования строки в массив байтов.

Если это недоступно в вашей версии Java, вы можете использовать ту же функциональность из проекта Apache Commons Codec.

Комментарии:

1. теперь я могу декодировать его, используя приведенный ниже код. byte[] imageByte= Base64.decodeBase64(response.getImageString()); Но мне нужно изменить его на формат файла (или изображения)

2. нет. я декодировал строку только в byte [], но я хочу изменить ее в файле.

3. Ну, тогда вам просто нужно записать массив байтов в файл, например, с помощью FileWriter .

4. FileWriter предназначен для текстовых файлов. FileOutputStream был бы более подходящим.

5. Понял. Не проверял должным образом. Спасибо за комментарий.

Ответ №3:

Если вы используете Spring, вы можете рассмотреть возможность использования HttpMessageConverter для преобразования вашего изображения в BufferedImage до того, как оно достигнет ваших контроллеров. Я не смог найти уже созданный в spring converters (может быть, я пропустил его?). В любом случае это то, что я только что написал. Возможно, вы сможете его улучшить.

  package com.stuff;

    import java.awt.image.BufferedImage;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.StringWriter;
    import java.util.ArrayList;
    import java.util.List;

    import javax.imageio.ImageIO;

    import org.apache.commons.codec.binary.Base64;
    import org.apache.commons.io.IOUtils;
    import org.apache.log4j.Logger;
    import org.springframework.http.HttpInputMessage;
    import org.springframework.http.HttpOutputMessage;
    import org.springframework.http.MediaType;
    import org.springframework.http.converter.AbstractHttpMessageConverter;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.http.converter.HttpMessageNotWritableException;

    /**
     * @author John Deverall
     */
    public class Base64EncodedImageHttpMessageConverter extends
            AbstractHttpMessageConverter<BufferedImage> {

        private Logger logger = Logger.getLogger(this.getClass());

        public Base64EncodedImageHttpMessageConverter() {

            List<MediaType> mediaTypes = new ArrayList<MediaType>();
            String[] supportedMediaTypes = ImageIO.getReaderMIMETypes();
            for (String supportedMediaType : supportedMediaTypes) {
                String[] typeAndSubtype = supportedMediaType.split("/");
                mediaTypes.add(new MediaType(typeAndSubtype[0], typeAndSubtype[1]));
            }

            setSupportedMediaTypes(mediaTypes);   
        }

        @Override
        protected boolean supports(Class<?> clazz) {
            return clazz.equals(BufferedImage.class);
        }

        /** This uses a data uri. If that's not you, 
         * you'll need to modify this method to decode the base64 data
         * straight. */
        @Override
        protected BufferedImage readInternal(Class<? extends BufferedImage> clazz,
                HttpInputMessage inputMessage) throws IOException,
                HttpMessageNotReadableException {

            StringWriter writer = new StringWriter();
            IOUtils.copy(inputMessage.getBody(), writer, "UTF-8");
            String imageInBase64 = writer.toString();
            int startOfBase64Data = imageInBase64.indexOf(",")   1;
            imageInBase64 = imageInBase64.substring(startOfBase64Data,
                    imageInBase64.length());

            if (Base64.isBase64(imageInBase64) == false) {
                logger.error("************************************************");
                logger.error("*** IMAGE IN REQUEST IS NOT IN BASE64 FORMAT ***");
                logger.error("************************************************");
            }

            byte[] decodeBase64 = Base64.decodeBase64(imageInBase64);
            BufferedImage image = ImageIO.read(new ByteArrayInputStream(
                    decodeBase64));
            return image;

        }     

    @Override
    protected void writeInternal(BufferedImage t,
                HttpOutputMessage outputMessage) throws IOException,
                HttpMessageNotWritableException {
            ImageIO.write(t, "jpeg", outputMessage.getBody());
            outputMessage.getBody().flush();
        }

    }
  

Затем в вашем контроллере напишите что-то вроде этого (или, предпочтительно, передайте BufferedImage какому-либо сервису). Обратите внимание, что логика преобразования из base64 в BufferedImage повторно используется и скрыта в HttpMessageConverter.

 @RequestMapping(value = "/image", method = RequestMethod.POST)
    public @ResponseBody void saveImage(@PathVariable String memberId, @RequestBody BufferedImage image)  {     
        someService.setBufferedImage(image);
    }



@RequestMapping(produces = MediaType.IMAGE_JPEG_VALUE, value = "/image", method = RequestMethod.GET)
    public @ResponseBody BufferedImage getImage() { 
        BufferedImage image = someService.getBufferedImage();
        return image;
    }
  

Если вы используете конфигурацию Java spring, конфигурация HttpMessageConverters выглядит примерно так

     @Configuration
    @EnableWebMvc
    public class ApplicationConfig extends WebMvcConfigurerAdapter {

    @Override
        public void configureMessageConverters(
                List<HttpMessageConverter<?>> converters) {
            converters.add(getJsonConverter());
            converters.add(getImageConverter());
            super.configureMessageConverters(converters);
        }

        @Bean
        GsonHttpMessageConverter getJsonConverter() { 
            GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
            return converter;
        }

        @Bean
        Base64EncodedImageHttpMessageConverter getImageConverter() { 
            Base64EncodedImageHttpMessageConverter converter = new Base64EncodedImageHttpMessageConverter();
            return converter;
        }

}
  

Если хотите, вы можете избежать использования apache commons, если вам это не нужно, и просто использовать новый класс java8 java.util.base64. GsonHttpMessageConverter (для преобразования Json в объекты моего домена) также не используется для изображений, поэтому вы можете извлечь его из конфигурации, если изображения — это все, что вы делаете.

Комментарии:

1. Обратите внимание, что вы также можете избежать использования apache commons здесь, если вам это не нужно, и просто использовать новый класс java8 java.util.base64. GsonHttpMessageConverter (для преобразования Json в объекты моего домена) также не используется для изображений, поэтому вы можете извлечь его из конфигурации, если изображения — это все, что вы делаете.

Ответ №4:

У меня работает следующее:

 package com.SmartBitPixel.XYZ.pqr.Controllers;

import java.util.Base64;    
import java.io.BufferedOutputStream;    
import java.io.File;    
import java.io.FileOutputStream;    
import java.util.Base64;    
import java.util.List;    
import java.util.Locale;    
import javax.servlet.http.HttpServletRequest;    
import org.slf4j.Logger;    
import org.slf4j.LoggerFactory;    
import org.springframework.beans.factory.annotation.Autowired;    
import org.springframework.beans.factory.annotation.Qualifier;    
import org.springframework.stereotype.Controller;    
import org.springframework.ui.Model;    
import org.springframework.web.bind.annotation.ModelAttribute;    
import org.springframework.web.bind.annotation.PathVariable;    
import org.springframework.web.bind.annotation.RequestMapping;    
import org.springframework.web.bind.annotation.RequestMethod;    
import org.springframework.web.bind.annotation.RequestParam;    
import org.springframework.web.multipart.MultipartFile;    

@Controller    
public class MainDocController     
{    
  @RequestMapping(value="/ProfileRegSubmit", method=RequestMethod.POST)
    public String handleFileUpload( 
            @RequestParam("fName") String fName, @RequestParam("lName") String lName,
            @RequestParam("imgName") String imgName, @RequestParam("webcamScanImage") String scanImageFile )
    {       

        if (!scanImageFile.isEmpty()) 
        {
            try 
            {               
                byte[] scanBytes = Base64.getDecoder().decode(scanImageFile);


                                ///////////////////////////////////////////////////////////////
                // Creating the directory to store file/data/image ////////////

                String rootPath = System.getProperty("catalina.home");

                File fileSaveDir = new File(rootPath   File.separator   SAVE_DIR);

                // Creates the save directory if it does not exists
                if (!fileSaveDir.exists()) 
                {
                    fileSaveDir.mkdirs();
                }

                File scanFile = new File( fileSaveDir.getAbsolutePath()   File.separator   "scanImageFile.png");
                BufferedOutputStream scanStream = new BufferedOutputStream( new FileOutputStream( scanFile ) );       
                scanStream.write(scanBytes);
                scanStream.close();

                returnStr = "RegisterSuccessful";

            }
            catch (Exception e) 
            {
                returnStr = "You failed to upload scanImageFile => "   e.getMessage();
            }
        }
        else 
        {
            returnStr = "You failed to upload scanImageFile because the file is empty.";
        }
    }
}