SpringMVC 接收方法的参数自定义转换,下面例子实现客户端发送图片的Base64数据,服务器转换为自定义的对象。
1. 首先,需要配置自定义的转换器。
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="com.mumu.support.spring.Base64ToFileConverter"></bean>
</mvc:argument-resolvers>
</mvc:annotation-driven>
2. 添加注解RequestBase64和实体类Base64File。并实现Base64ToFileConverter(实现org.springframework.web.method.support.HandlerMethodArgumentResolver接口)
1) 注解RequestBase64
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBase64 {
}
2) 实体类Base64File
public class Base64File {
private String imageType;
private byte[] content;
public Base64File() {
}
public Base64File(String imageType, byte[] content) {
super();
this.imageType = imageType;
this.content = content;
}
public boolean isEmpty() {
return ArrayUtils.isEmpty(content);
}
public long getSize() {
return content != null? content.length:0L;
}
public byte[] getBytes() throws IOException {
return content;
}
public String getImageType() {
return imageType;
}
public InputStream getInputStream() throws IOException {
ByteArrayInputStream bais = new ByteArrayInputStream(content);
return bais;
}
public void transferTo(File dest) throws IOException, IllegalStateException {
if(isEmpty()){
return;
}
try(FileOutputStream fos = new FileOutputStream(dest);){
fos.write(content, 0, content.length);
}
}
}
3) Base64ToFileConverter
public class Base64ToFileConverter implements HandlerMethodArgumentResolver{
private static Pattern pattern = Pattern.compile("data:([^;]*);base64,(.+)", Pattern.CASE_INSENSITIVE);
public Base64ToFileConverter(){
}
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(RequestBase64.class);
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
String[] values = webRequest.getParameterValues(parameter.getParameterName());
if(ArrayUtils.isNotEmpty(values)){
if(parameter.getParameterType().isAssignableFrom(Base64File.class)){
return toContent(values[0]);
}else if(parameter.getParameterType().isAssignableFrom(List.class)){
List<Base64File> list = new ArrayList<>(values.length);
for(String value : values){
list.add(toContent(value));
}
return list;
}else if(parameter.getParameterType().isArray()){
Base64File[] bfs = new Base64File[values.length];
int index = 0;
for(String value : values){
bfs[index++] = toContent(value);
}
return bfs;
}
}
return null;
}
private Base64File toContent(String value){
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
try
{
Matcher matcher = pattern.matcher(value);
if(matcher.find()){
String imageType = matcher.group(1);
String content = matcher.group(2);
//Base64解码
byte[] b = decoder.decodeBuffer(content);
return new Base64File(imageType, b);
}
return null;
}catch(Exception e){
throw new I18NIllegalArgumentException(e);
}
}
public static void main(String[] args) {
String value = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAeCAIAAACwp+nIAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADxSURBVEhL7ZU7DoMwEESXVNBRUsKtuAHcgmNAyS3gZtCRER5FkYw/66AUUV4BK2OeZmWxZMdxyN08eL+VH5Cu69o0TeYAj+Z55lYbHNQldV1zh4M8z7nVwpm06zpWDvZ9Z2VDeRzjOPK1E65aKKTLspRlSZ9I3/d8YKGQVlVFn8i2bVy9Ilb63rgnoyFW+orZti2X3ERJ32P6GzdESVUxQViqjQnCUm1MEJAmxAQBaUJMEJj8GEimQExMEFMH8c3TaZpYnTOJVQwm8CVpvQNf+0VRmPmm6h342h+GAVd86brecRKepMl898f3CX/p3Yg8AZMYt/pV+plfAAAAAElFTkSuQmCC";
Matcher matcher = pattern.matcher(value);
if(matcher.find()){
String imageType = matcher.group(1);
String content = matcher.group(2);
System.out.println(imageType + " " + content);
}
}
}
3. Controller中方法实现
@RequestMapping(value = "/testing", method = RequestMethod.POST)
@ResponseBody
public ResultVO testing(@RequestBase64 Base64File file, @RequestBase64 List<Base64File> file2) {
try {
System.out.println(Arrays.toString(file.getBytes()));
System.out.println("=============================");
file2.stream().forEach(new Consumer<Base64File>() {
@Override
public void accept(Base64File t) {
try {
System.out.println(Arrays.toString(t.getBytes()));
} catch (IOException e) {
e.printStackTrace();
}
}
});
file.transferTo(new File("d:/test.jpg"));
} catch (IOException e) {
e.printStackTrace();
}
return ResultVO.successVO();
}
注意事项: 参数前面不能加@RequestParam,否则org.springframework.web.method.annotation.RequestParamMethodArgumentResolver会处理参数解析