阿里云OSS上传图片教程-附案例

2年前 (2022) 程序员胖胖胖虎阿
294 0 0

一、阿里云账号及OSS配置

购买资源包,可按年按月付费,也可按照流量计费。根据自己需要购买。

阿里云OSS上传图片教程-附案例

1、创建Bucket--创建Bucket

注意:本次选择的华北2,不同地区的代码对接中配置不一样

阿里云OSS上传图片教程-附案例

存储类型:

标准存储:高可用、高性能的,基本的数据访问,用于正常网站访问,保证数据量大的网站读写能力。

低频访问存储:一般用于上传的东西很少有人访问,用于自己的数据存储和学习,收费低于标准存储

归档存储:用于数据归档,基本出问题才需要去查看的数据,收费低于低频访问存储。

冷归档存储:用于数据归档,基本不访问,收费低于归档存储。

阿里云OSS上传图片教程-附案例

 读写权限选择公共读:写入需要配置参数进行授权写入,上传的资源,所有人都能通过链接访问。

阿里云OSS上传图片教程-附案例

点击Bucket列表名称,进入Bucket存储目录,添加目录名称

存储路径(FOLDER)

阿里云OSS上传图片教程-附案例

准备配置的秘钥(ACCESS_KEY_ID、ACCESS_KEY_SECRET)Bucket名称(BACKET_NAME)、存储路径(FOLDER)、外网域名(ENDPOINT)

秘钥(ACCESS_KEY_ID、ACCESS_KEY_SECRET)--老版本

阿里云OSS上传图片教程-附案例

Bucket名称(BACKET_NAME)

阿里云OSS上传图片教程-附案例

 外网域名

阿里云OSS上传图片教程-附案例

二、代码配置

OSSClientConstants 基本参数配置类,此处也可设置到配置项中

阿里云OSS上传图片教程-附案例

Jar包引入

<!-- 阿里云oss -->
<dependency>
    <groupId>com.aliyun.oss</groupId>
    <artifactId>aliyun-sdk-oss</artifactId>
    <version>3.0.0</version>
</dependency>

AliyunOSSClientUtil工具类

package com.central.file.config.aliyun;



import com.alibaba.nacos.client.naming.utils.StringUtils;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.Bucket;
import com.aliyun.oss.model.OSSObject;
import com.aliyun.oss.model.ObjectMetadata;
import com.aliyun.oss.model.PutObjectResult;
import com.central.common.utils.DateUtils;
import com.central.file.utils.UUIDUtils;
import com.sun.deploy.net.HttpUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;



/**
 * @author sang
 * @class:AliyunOSSClientUtil
 * @descript:java使用阿里云OSS存储对象上传图片
 * @date:2022年3月16日 下午5:58:08
 */
public class AliyunOSSClientUtil{

    private static final Logger log = LoggerFactory.getLogger(HttpUtils.class);

    private long bytesWritten = 0;
    private long totalBytes = -1;
    private boolean succeed = false;

    private static String number;


    //阿里云API的内或外网域名
    private static String ENDPOINT;
    //阿里云API的密钥Access Key ID
    private static String ACCESS_KEY_ID;
    //阿里云API的密钥Access Key Secret
    private static String ACCESS_KEY_SECRET;
    //阿里云API的bucket名称
    private static String BACKET_NAME;
    //阿里云API的文件夹名称
    private static String FOLDER;

    //初始化
    /* private static  OSSClient ossClient=AliyunOSSClientUtil.getOSSClient();*/
    //初始化属性
    static {
        ENDPOINT = OSSClientConstants.ENDPOINT;
        ACCESS_KEY_ID = OSSClientConstants.ACCESS_KEY_ID;
        ACCESS_KEY_SECRET = OSSClientConstants.ACCESS_KEY_SECRET;
        BACKET_NAME = OSSClientConstants.BACKET_NAME;
        FOLDER = OSSClientConstants.FOLDER;
    }

    /**
     * 获取阿里云OSS客户端对象
     *
     * @return ossClient
     */
    public static OSSClient getOSSClient() {
        ClientBuilderConfiguration conf = new ClientBuilderConfiguration(); // 连接空闲超时时间,超时则关闭
        conf.setIdleConnectionTime(1000); // 在这里可以做一些配置,比如超时时间、最大连
        return new OSSClient(ENDPOINT, ACCESS_KEY_ID, ACCESS_KEY_SECRET);
    }

    /**
     * 创建存储空间
     *
     * @param ossClient  OSS连接
     * @param bucketName 存储空间
     * @return
     */
    public static String createBucketName(OSSClient ossClient, String bucketName) {
        //存储空间
        final String bucketNames = bucketName;
        if (!ossClient.doesBucketExist(bucketName)) {
            //创建存储空间
            Bucket bucket = ossClient.createBucket(bucketName);
            log.info("创建存储空间成功");
            return bucket.getName();
        }
        return bucketNames;
    }

    /**
     * 删除存储空间buckName
     *
     * @param ossClient  oss对象
     * @param bucketName 存储空间
     */
    public static void deleteBucket(OSSClient ossClient, String bucketName) {
        ossClient.deleteBucket(bucketName);
        log.info("删除" + bucketName + "Bucket成功");
    }

    /**
     * 创建模拟文件夹
     *
     * @param ossClient  oss连接
     * @param bucketName 存储空间
     * @param folder     模拟文件夹名如"qj_nanjing/"
     * @return 文件夹名
     */
    public static String createFolder(OSSClient ossClient, String bucketName, String folder) {
        //文件夹名
        final String keySuffixWithSlash = folder;
        //判断文件夹是否存在,不存在则创建
        if (!ossClient.doesObjectExist(bucketName, keySuffixWithSlash)) {
            //创建文件夹
            ossClient.putObject(bucketName, keySuffixWithSlash, new ByteArrayInputStream(new byte[0]));
            log.info("创建文件夹成功");
            //得到文件夹名
            OSSObject object = ossClient.getObject(bucketName, keySuffixWithSlash);
            String fileDir = object.getKey();
            return fileDir;
        }
        return keySuffixWithSlash;
    }

    /**
     * 根据key删除OSS服务器上的文件
     *
     * @param ossClient  oss连接
     * @param bucketName 存储空间
     * @param folder     模拟文件夹名 如"qj_nanjing/"
     * @param key        Bucket下的文件的路径名+文件名 如:"upload/cake.jpg"
     */
    public static void deleteFile(OSSClient ossClient, String bucketName, String folder, String key) {
        ossClient.deleteObject(bucketName, folder + key);
        log.info("删除" + bucketName + "下的文件" + folder + key + "成功");
    }


    //测试
    public void main(String[] args) {
        //初始化OSSClient
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        //上传文件
        String imgPath = "C:\\Users\\yaya\\Pictures\\内控项目图片\\yuan.png";
        String[] file = imgPath.split(",");
        for (String filename : file) {
            //System.out.println("filename:"+filename);
            File filess = new File(filename);
            String md5key = this.uploadObject2OSS(ossClient, filess, BACKET_NAME, FOLDER).get("resultStr").toString();
            log.info("上传后的文件MD5数字唯一签名:" + md5key);
            //上传后的文件MD5数字唯一签名:40F4131427068E08451D37F02021473A
        }
    }

    /**
     * 上传图片至OSS
     *
     * @param ossClient  oss连接
     * @param file       上传文件(文件全路径如:D:\\image\\cake.jpg)
     * @param bucketName 存储空间
     * @param folder     模拟文件夹名 如"qj_nanjing/"
     * @return Map 返回的唯一MD5数字签名 以及 对应的上传到文件的key
     */
    public Map<String, Object> uploadObject2OSS(OSSClient ossClient, File file, String bucketName, String folder) {
        String resultStr = null;
        Map map = new HashMap();
        try {
            //以输入流的形式上传文件
            InputStream is = new FileInputStream(file);
            //文件名
            String fileName = file.getName();
            fileName.replace("/", "").replace("\\", "");
            fileName = fileName.substring(0, fileName.lastIndexOf("."))
                    + UUIDUtils.getUUID() + fileName.substring(fileName.lastIndexOf("."));
            // key的组成
            /*String newFileName= UUID.randomUUID().toString();*/
            //文件大小
            Long fileSize = file.length();
            //创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            //上传的文件的长度
            metadata.setContentLength(is.available());
            //指定该Object被下载时的网页的缓存行为
            metadata.setCacheControl("no-cache");
            //指定该Object下设置Header
            metadata.setHeader("Pragma", "no-cache");
            //指定该Object被下载时的内容编码格式
            metadata.setContentEncoding("utf-8");
            //文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
            //如果没有扩展名则填默认值application/octet-stream
            metadata.setContentType(this.getContentType(fileName));
            //指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            //上传文件   (上传文件流的形式)
            PutObjectResult putResult = ossClient.putObject(bucketName, fileName, is, metadata);
            //解析结果
            System.out.println(this.getUrl(fileName));
            resultStr = putResult.getETag();
            map.put("resultStr", resultStr);
            map.put("imageUrl", fileName);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return map;
    }

    /**
     * 通过文件名判断并获取OSS服务文件上传时文件的contentType
     *
     * @param fileName 文件名
     * @return 文件的contentType
     */
    public  String getContentType(String fileName) {
        //文件的后缀名
        String fileExtension = fileName.substring(fileName.lastIndexOf("."));
        if (".bmp".equalsIgnoreCase(fileExtension)) {
            return "image/bmp";
        }
        if (".gif".equalsIgnoreCase(fileExtension)) {
            return "image/gif";
        }
        if (".jpeg".equalsIgnoreCase(fileExtension) || ".jpg".equalsIgnoreCase(fileExtension) || ".png".equalsIgnoreCase(fileExtension)) {
            return "image/jpeg";
        }
        if (".html".equalsIgnoreCase(fileExtension)) {
            return "text/html";
        }
        if (".txt".equalsIgnoreCase(fileExtension)) {
            return "text/plain";
        }
        if (".vsd".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.visio";
        }
        if (".ppt".equalsIgnoreCase(fileExtension) || "pptx".equalsIgnoreCase(fileExtension)) {
            return "application/vnd.ms-powerpoint";
        }
        if (".doc".equalsIgnoreCase(fileExtension) || "docx".equalsIgnoreCase(fileExtension)) {
            return "application/msword";
        }
        if (".xml".equalsIgnoreCase(fileExtension)) {
            return "text/xml";
        }
        if (".flv".equalsIgnoreCase(fileExtension)) {
            return "video/x-flv";
        }
        if (".mp3".equalsIgnoreCase(fileExtension)) {
            return "audio/mpeg";
        }
        if (".mp4".equalsIgnoreCase(fileExtension)) {
            return "video/mp4";
        }

        //默认返回类型
        return "image/jpeg";
    }

    //通过key获取到上传文件的地址
    public String getUrl(String key) {
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        // 设置URL过期时间为10年  3600l* 1000*24*365*10
        Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24 * 365 * 10);
        // 生成URL
        URL url = ossClient.generatePresignedUrl(BACKET_NAME, key, expiration);
        if (url != null) {
            return url.toString().split("\\?")[0];
        }
        return null;
    }


    /**
     * 上传图片至OSS
     *
     * @param ossClient                    oss连接
     * @param (文件全路径如:D:\\image\\cake.jpg)
     * @param bucketName                   存储空间
     * @param folder                       模拟文件夹名 如"qj_nanjing/"
     * @return Map 返回的唯一MD5数字签名 以及 对应的上传到文件的key
     */
    public  Map<String, Object> uploadObject2OSSnew(OSSClient ossClient, MultipartFile f, String bucketName, String folder, String bisType,String sessionKey) {
        number = sessionKey;
        String resultStr = null;
        Map map = new HashMap();
        try {
            //以输入流的形式上传文件
            InputStream is = f.getInputStream();
            //文件名
            String fileName = f.getOriginalFilename();
            if (fileName.lastIndexOf(".") == -1) {
                fileName = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + "/" + Calendar.getInstance().getTimeInMillis() + ".jpg";
            }
            fileName.replace("/", "").replace("\\", "");
            if ("".equals(fileName)) {
                fileName = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + Calendar.getInstance().getTimeInMillis() + ".jpg";
            } else {
                fileName = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD) + "/" + fileName.substring(0, fileName.lastIndexOf(".")) + Calendar.getInstance().getTimeInMillis() + fileName.substring(fileName.lastIndexOf("."), fileName.length());
            }
            if (StringUtils.isNotEmpty(bisType)) {
                fileName = bisType + "/" + fileName;
            }
            if(StringUtils.isNotEmpty(folder)){
                fileName = folder + "/" + fileName;
            }

            // key的组成
            /*String newFileName= UUID.randomUUID().toString();*/
            //文件大小
            Long fileSize = f.getSize();
            //创建上传Object的Metadata
            ObjectMetadata metadata = new ObjectMetadata();
            //上传的文件的长度
            metadata.setContentLength(is.available());
            //指定该Object被下载时的网页的缓存行为
            metadata.setCacheControl("no-cache");
            //指定该Object下设置Header
            metadata.setHeader("Pragma", "no-cache");
            //指定该Object被下载时的内容编码格式
            metadata.setContentEncoding("utf-8");
            //文件的MIME,定义文件的类型及网页编码,决定浏览器将以什么形式、什么编码读取文件。如果用户没有指定则根据Key或文件名的扩展名生成,
            //如果没有扩展名则填默认值application/octet-stream
            metadata.setContentType(f.getContentType());
            //指定该Object被下载时的名称(指示MINME用户代理如何显示附加的文件,打开或下载,及文件名称)
            metadata.setContentDisposition("filename/filesize=" + fileName + "/" + fileSize + "Byte.");
            //上传文件   (上传文件流的形式)
            PutObjectResult putResult = ossClient.putObject(bucketName, fileName, is, metadata);
            // 带进度条的上传。
            //解析结果
            System.out.println(getUrl(fileName));
            resultStr = putResult.getETag();
            map.put("resultStr", resultStr);
            map.put("guid", fileName);
            map.put("imageUrl", getUrl(fileName));
            System.out.println(map);
            // 关闭OSSClient。
            ossClient.shutdown();
        } catch (Exception e) {
            e.printStackTrace();
            log.error("上传阿里云OSS服务器异常." + e.getMessage(), e);
        }
        return map;
    }

    //上传返回url
    public String getFileUrl(File file) {
        //上传图片 file 文件 folder 文件夹名字
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        Map map = uploadObject2OSS(ossClient, file, BACKET_NAME, FOLDER);
        return this.getUrl(map.get("imageUrl").toString());
    }

    public String getFileUrlNew(MultipartFile m, String bisType,String sessionKey) {
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        Map map = this.uploadObject2OSSnew(ossClient, m, BACKET_NAME, FOLDER, bisType,sessionKey);
        return map.get("imageUrl").toString();
    }

    public Map<String, String> getFileUrlNewFlow(MultipartFile m, String bisType) {
        OSSClient ossClient = AliyunOSSClientUtil.getOSSClient();
        Map map = this.uploadObject2OSSnew(ossClient, m, BACKET_NAME, FOLDER, bisType,"");
        return map;
    }


}

AliyunOSSAutoConfigure上传下载方法

package com.central.file.config;

import com.aliyun.oss.common.auth.DefaultCredentialProvider;
import com.central.file.model.FileInfo;
import com.central.file.properties.FileServerProperties;
import com.central.file.service.impl.AbstractIFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.aliyun.oss.OSSClient;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

/**
 * 阿里云配置
 *
 * @author koko
 */
@Configuration
@ConditionalOnProperty(name = "cgs.file-server.type", havingValue = "aliyun")
public class AliyunOSSAutoConfigure {
    @Autowired
    private FileServerProperties fileProperties;

    /**
     * 阿里云文件存储client
     * 只有配置了aliyun.oss.access-key才可以使用
     */
    @Bean
    public OSSClient ossClient() {
        OSSClient ossClient = new OSSClient(fileProperties.getOss().getEndpoint()
                , new DefaultCredentialProvider(fileProperties.getOss().getAccessKey(), fileProperties.getOss().getAccessKeySecret())
                , null);
        return ossClient;
    }

    @Service
    public class AliyunOssServiceImpl extends AbstractIFileService {
        @Autowired
        private OSSClient ossClient;

        @Override
        protected String fileType() {
            return fileProperties.getType();
        }

        @Override
        protected void uploadFile(MultipartFile file, FileInfo fileInfo) throws Exception {
            ossClient.putObject(fileProperties.getOss().getBucketName(), fileInfo.getName(), file.getInputStream());
            fileInfo.setUrl(fileProperties.getOss().getDomain() + "/" + fileInfo.getName());
        }

        @Override
        protected boolean deleteFile(FileInfo fileInfo) {
            ossClient.deleteObject(fileProperties.getOss().getBucketName(), fileInfo.getName());
            return true;
        }
    }
}

阿里云上传接口访问(uploadImg)

package com.central.file.controller;

import com.central.common.model.PageResult;
import com.central.common.model.Result;
import com.central.common.utils.DateUtils;
import com.central.file.config.aliyun.AliyunOSSClientUtil;
import com.central.file.config.qiniu.UtilsUpload;
import com.central.file.model.FileInfo;
import com.central.file.model.ReturnMovo;
import com.central.file.service.IFileService;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.File;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * 文件上传
 *
 * @author koko
 */
@Log4j2
@Controller
@RequestMapping("/aliyunFile")
@CrossOrigin
public class AliyunFileController {
    @Resource
    private IFileService fileService;
    @Autowired
    private Environment environment;
    /*@Resource
    private UserService userService;*/
    /**
     * 文件上传
     * 根据fileType选择上传方式
     *
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/files-anon")
    public FileInfo upload(@RequestParam("file") MultipartFile file) throws Exception {

        return fileService.upload(file);
    }

    /***
     * 阿里云上传图片
     */
    @RequestMapping("uploadImg")
    @ResponseBody
    public FileInfo uploadImg(@RequestParam MultipartFile file) {
        FileInfo resultModel = new FileInfo();
        Map<String, Object> map = new HashMap<>();
        try {
            if (!file.isEmpty()) {
                String avatar = new AliyunOSSClientUtil().getFileUrlNew(file, "", "");
                resultModel.setStatus(0);
                resultModel.setMsg("保存成功");
                resultModel.setPath(avatar);
                return resultModel;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }




//    /**
//     * 上传文件
//     */
//    @PostMapping("/updateFile")
//    @ResponseBody
//    public FileInfo updateFile(@RequestParam("file") MultipartFile file) {
//        FileInfo fileInfo = new FileInfo();
//
//        try {
//            if (!file.isEmpty()) {
//                String url = UtilsUpload.uploadImgByMultipartFile(file,false);
//                fileInfo.setUrl(url);
//            }
//        } catch (Exception e) {
//            fileInfo.setStatus(1);
//            fileInfo.setMsg("文件上传失败");
//        }
//        return fileInfo;
//    }

    /**
     * 上传文件
     */
    @PostMapping("/updateFile")
    @ResponseBody
    public FileInfo uploadFile(@RequestParam("file") MultipartFile file){
        FileInfo fileInfo = new FileInfo();
        // 判断文件是否为空
        String filePath = "";
        String filename = file.getOriginalFilename();
        //获取当前时间
        String timeStr = DateUtils.YMD.format(new Date());
        if (!file.isEmpty()) {
            try {
                //判断文件目录是否存在,否则自动生成
                File directory = new File(environment.getProperty("upload")+timeStr);
                    if (!directory.exists()){
                    directory.mkdir();
                }
                //失败跳转视图

                //获取图片扩展名
//                String ext = filename.substring(filename.lastIndexOf("."));
//                filename = StringUtils.gainGUID() +ext;
                // 文件保存路径
                filePath =  FilenameUtils.concat(environment.getProperty("upload")+timeStr, filename);
                // 转存文件
                file.transferTo(new File(filePath));

                fileInfo.setUrl(environment.getProperty("fileupload.directory")+timeStr+"/"+filename);
            } catch (Exception e) {
                e.printStackTrace();
                fileInfo.setStatus(1);
                fileInfo.setMsg("文件上传失败");
            }
        }
        //成功跳转视图
        return fileInfo;
    }

    @PostMapping("/updateFileEdit")
    @ResponseBody
    public ReturnMovo updateFileEdit(MultipartFile file) {
        ReturnMovo returnMovo = new ReturnMovo();
        Map<String, Object> map = new HashMap<>();
        try {
            if (!file.isEmpty()) {
                String url = UtilsUpload.uploadImgByMultipartFile(file,false);
                map.put("src", url);
                returnMovo.setData(map);
            }
        } catch (Exception e) {
            returnMovo.setCode(1);
            returnMovo.setMsg("文件上传失败");
        }
        return returnMovo;
    }

    /**
     * 文件删除
     *
     * @param id
     */
    @DeleteMapping("/files/{id}")
    public Result delete(@PathVariable String id) {
        try {
            fileService.delete(id);
            return Result.succeed("操作成功");
        } catch (Exception ex) {
            return Result.failed("操作失败");
        }
    }

    /**
     * 文件查询
     *
     * @param params
     * @return
     */
    @GetMapping("/files")
    public PageResult<FileInfo> findFiles(@RequestParam Map<String, Object> params) {
        return fileService.findList(params);
    }
}

前端就不写了,就是一种是单文件上传,另一种多文件上传。控件很多,有空再写。

如果还不会,此处是阿里云OSS+七牛云和文件存储本地+FastDFS+的文件存储代码。

版权声明: 程序员胖胖胖虎阿 发表于 2022年10月4日 上午9:08。
转载请注明: 阿里云OSS上传图片教程-附案例 | 胖虎的工具箱-编程导航

相关文章

面试连环炮系列(二十️四):为什么选择RocketMQ
Java-反射机制(超详解)
Ruoyi从mysql切换到postgresql的几个坑
idea的最新 激活码(IDEA2019 破解教程,每日更新)
idea的最新激活破解教程(IDEA安装及破解插件永久有效)
IDEA2019免费激活码(IDEA最新破解图文教程,激活破解教程)

暂无评论

暂无评论...

PHP网站源码广州网站推广坪地企业网站建设惠州百度标王龙华至尊标王永湖网站关键词优化松岗网站优化排名东莞模板制作西乡网页制作龙华seo大鹏网站设计模板西乡企业网站制作石岩关键词按天收费大芬SEO按天收费光明百度爱采购大浪seo优化坑梓网站定制荷坳网站seo优化东莞关键词排名包年推广丹竹头网站建设福田SEO按天计费大浪百度网站优化排名惠州网站推广方案民治网络推广东莞百度竞价双龙建站永湖模板网站建设松岗SEO按效果付费光明品牌网站设计沙井关键词按天收费坂田模板制作歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

PHP网站源码 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化