我正在使用 spring 编写一个网络服务。
该服务将base64编码的图像作为字符串参数。
我想将此字符串解码为图像并上传到服务器。
@RequestMapping(value="/uploadImage",method = RequestMethod.POST)
public @ResponseBody String uploadImage(@RequestParam("encodedImage") String encodedImage)
{
byte[] imageByte= Base64.decodeBase64(encodedImage);
return null;
}
以下代码将base64字符串解码为byte[]并将其内容上传到服务器。
这对我来说效果很好。
@PostMapping("/uploadImage2")
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;
}
}
如果您使用 Spring,您可以考虑使用 HttpMessageConverter 在图像到达控制器之前将其转换为 BufferedImage。我在弹簧转换器中找不到已经制作好的弹簧转换器(也许我错过了?)。无论如何,这是我现在刚刚写的东西。你也许可以改进它。
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;
}
如果你使用spring的java配置,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 转换为我的域对象)也不用于图像,因此如果您所做的只是图像,则可以将其从配置中提取出来。
以下对我有用:
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.";
}
}
}