2021SC@SDUSC-SDUDOC-blog09

2021SC@SDUSC
中午和刘同学一起找戴老师查验了svg demo,进一步明确项目的用例规范方便未来扩展开发。
后端数据库部分,本周分析sdudoc-mysql的图片部分。
文件夹结构:
在这里插入图片描述
(古籍文章切分后,字、词组等在前端以svg格式呈现)
可见controller模块分图片、文章两部分,本篇主要分析ImgServiceController、ImgServiceImpl中出现的知识点。(见代码注释)

ImgServiceController

public class ImgServiceController {

    @Autowired
    ImgService service;

    @RequestMapping(value = "/get_latest_id", method = RequestMethod.POST)
    

    public Long getLatestNewId() {
        return service.getLatestId() + 1;
    }

    @RequestMapping(value = "/save_by_base64", method = RequestMethod.POST, produces = "application/json")
    public Long save(@RequestBody JSONObject data) {
        return service.save(data.getString("base64").replaceAll(" ", "+"), data.getString("filename"));
    }

    @RequestMapping(value = "/get_by_id", method = RequestMethod.GET)
    public byte[] getImgById(Long id) {
        return service.getImgById(id);
    }

    @RequestMapping(value = "/get_by_url", method = RequestMethod.GET)
    public byte[] getImgByUrl(String url) {
        return Base64Util.base64Decode2Bytes(service.getImgByUrl("" + url));
    }
}

此模块核心操作: @RequestMapping
比如:

  @RequestMapping(value = "/get_latest_id", method = RequestMethod.POST)

在Spring MVC 中使用 @RequestMapping 来映射请求,也就是通过它来指定控制器可以处理哪些URL请求,相当于Servlet中在web.xml中配置

    <servlet>
        <servlet-name>servletName</servlet-name>
        <servlet-class>ServletClass</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>servletName</servlet-name>
        <url-pattern>url</url-pattern>
    </servlet-mapping>

关于RequestMethod.POST:
RequestMethod是在@RequestMapping注解中使用的一个属性,用来标识请求的方法类型。
跳转requestMethod源码,可以看到封装进了8种类型:

   public enum RequestMethod {
    GET,
    HEAD,
    POST,
    PUT,
    PATCH,
    DELETE,
    OPTIONS,
    TRACE;
    private RequestMethod() {
    }
}

tips:
对于spring接口的method的get和post定义,在访问时这两种方式的效果有不同:
①将一个method定义成RequestMethod.GET时,可以直接通过地址访问,这非常方便我们在开发的时候调用到我们的接口并进行测试;
②同样的接口,将其method更改为RequestMethod.POST时,会发现接口在地址栏访问不了了,只有向服务器发起一个POST请求时才可以访问。

ImgServiceImpl

实现了ImgService接口,跳转查看ImgService :

public interface ImgService {

    public Long getLatestId();
    public Long save(String base64, String filename);
    public Long save(byte[] data);
    public byte[] getImgById(Long id);
    public byte[] getImgByUrl(String url);
    public Img fileChecksumExist(String checksum) throws IOException;
}

package cn.edu.sdu.service.impl;

import cn.edu.sdu.entity.ds1.Img;
import cn.edu.sdu.repository.ds1.ImgRepository;
import cn.edu.sdu.service.ImgService;
import cn.edu.sdu.util.Base64Util;
import cn.edu.sdu.util.FileChecksum;
import cn.edu.sdu.util.RandomPicNameUtil;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.Optional;

@Service
public class ImgServiceImpl implements ImgService {

    final ImgRepository repository;

    public ImgServiceImpl(ImgRepository repository) {
        this.repository = repository;
    }

    @Override
    public Long getLatestId() {
        Img img = new Img();
        return repository.count(Example.of(img));
    }

    @Override
    public Long save(String base64, String filename) {
        String[] d = base64.split("base64,");

        if (d.length == 2) {
//            String prefix = d[0];
            String data = d[1];

            byte[] bs = Base64Util.base64Decode2Bytes(data);
            for(int i = 0 ; i < bs.length; ++i) {
                if(bs[i] < 0) {
                    //调整异常数据
                    bs[i] += 256;
                }
            }

            String imgFilePath = generateImgUrl(filename);

            try {
                // 如果成功写入文件,记录在数据库里
                if (writeInFileByData(bs, imgFilePath)) {
                    // 比对校验和,如果数据库里没有,则写入数据库
                    String checksum = FileChecksum.checksumSHA256(bs);
                    Img img;
                    if ((img = fileChecksumExist(checksum)) == null) {
                        img = new Img();
                        img.setId(getLatestId() + 1L);
                        img.setUrl(imgFilePath);
                        img.setSha256(checksum);
                        repository.save(img);
                        return img.getId();
                    }
                    else {
                        // 数据库里有,则返回图片id
                        return img.getId();
//                        return randomName;
                    }
                } else {
                    return -4L;  // 写入文件失败
                }
            } catch (IOException e) {
                return -2L;
            }
        } else {
            return -3L;
//            return "图片格式不正确";
        }
    }

    @Override
    public Long save(byte[] data) {
        return null;
    }

    public boolean writeInFileByData(byte[] data, String imgFilePath) {
        boolean result = false;

        // 写入file
        OutputStream out = null;
        try {
            out = new FileOutputStream(imgFilePath);
            out.write(data);
            out.flush();
            out.close();

            result = true;
        } catch (IOException e) {
//            return -2L;
//            return "图片上传失败";
        }

        return result;
    }

    public String generateImgUrl(String filename) {
        // 生成图片存储路径
        String randomName = RandomPicNameUtil.getRandomName(filename);

        String imgFilePath = System.getProperty("user.dir");
        char separator = '/';
        if (imgFilePath.indexOf('/') < 0) {
            separator = '\\';
        }
        String dirName = separator + "webapps"
                + separator + "assets"
                + separator + "picture"
                + separator;
        File dir = new File(imgFilePath + dirName);
        if (!dir.exists() && !dir.mkdirs()) {
//            return -1L;
//            return "生成图片存储路径失败";
            return null;
        }

        imgFilePath = imgFilePath + dirName + randomName;

        return imgFilePath;
    }

    @Override
    public byte[] getImgById(Long id) {
        Optional<Img> op = repository.findById(id);
        if (op.isPresent()) {
            Img img = op.get();

            // 读取图片
            return getImgByUrl(img.getUrl());
        } else {
            return "找不到图片".getBytes(StandardCharsets.UTF_8);
        }
    }

    public byte[] getImgByUrl(String url) {
        try {
            InputStream in = new FileInputStream(url);
            byte[] data = new byte[in.available()];

            int n;
            while ((n = in.read(data)) == -1) break;

            in.close();

            return Base64Util.base64Encode2Bytes(data);
        } catch (IOException e) {
            e.printStackTrace();
            return "图片读取失败".getBytes(StandardCharsets.UTF_8);
        }
    }

    /**
     * 返回校验和是否存在
     * 存在返回Img,不存在返回null
     * */
    @Override
    public Img fileChecksumExist(String checksum) {
        Img img = new Img();
        img.setSha256(checksum);
        Optional<Img> one = repository.findOne(Example.of(img));

        return one.orElse(null);
    }

    public static void main(String[] args) {
        String imgFilePath = System.getProperty("user.dir");
        File dir = new File(imgFilePath + "\\webapps\\assets\\picture\\");
        System.out.println(dir.getPath());
        if (!dir.exists()) {
            System.out.println(dir.mkdirs());
        }
    }
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chi Z犬里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值