自动生成二维码,返回图片地址
本来不想写的,但是怕太久不写这个东西,就要荒废了,就先记录一下简单的东西
这里因为,返回地址的时候,通过了nginx ,我试了很多方法都抓取不到对应的IP地址,
就在nginx配置了一个地址,放在head里面了
接口里面直接可以用HttpServletRequest.getHead("") 抓取到地址,地址当然是写死的,
部署在什么ip上 就改成什么ip
希望有大神可以帮我解决这个问题
下面就先贴个代码吧
我们是java端,所以需要引这两个
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.2.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.2.1</version>
</dependency>
service 层
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
/**
* @ClassName QRCodeService
* @Description ***
* @uthor ***
* @Date ***
* @Version 1.0
*/
public interface QRCodeService {
//自动生成二维码,返回图片地址
String crateQRCode(String content, int width, int height,HttpServletRequest request) throws IOException;
}
impl层
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lb.modular.service.QRCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import lb.modular.file.PreReadUploadConfig;
import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.UUID;
import org.apache.commons.codec.binary.Base64;
import org.springframework.util.StringUtils;
import sun.misc.BASE64Decoder;
/**
* @ClassName QRCodeServiceImpl
* @Description his
* @uthor ***
* @Date ***
* @Version 1.0
*/
@Service
@Transactional
public class QRCodeServiceImpl implements QRCodeService {
@Autowired
private PreReadUploadConfig PreReadUploadConfig;
@Override
public String crateQRCode(String content, int width, int height, HttpServletRequest request) throws IOException {
String content1= String.valueOf(content);
String resultImage = "";
if (!StringUtils.isEmpty(content1)) {
ServletOutputStream stream = null;
ByteArrayOutputStream os = new ByteArrayOutputStream();
@SuppressWarnings("rawtypes")
HashMap<EncodeHintType, Comparable> hints = new HashMap<>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); // 指定字符编码为“utf-8”
hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); // 指定二维码的纠错等级为中级
hints.put(EncodeHintType.MARGIN, 2); // 设置图片的边距
String uuidrandom= String.valueOf(UUID.randomUUID());
try {
QRCodeWriter writer = new QRCodeWriter();
BitMatrix bitMatrix = writer.encode(content1, BarcodeFormat.QR_CODE, width, height, hints);
BufferedImage bufferedImage = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(bufferedImage, "png", os);
/**
* 原生转码前面没有 data:image/png;base64 这些字段,返回给前端是无法被解析,可以让前端加,也可以在下面加上
*/
// byte[] bytes = os.toByteArray();
resultImage = new String(Base64.encodeBase64(os.toByteArray()));
String str =resultImage;
// System.out.println(":"+str);
BASE64Decoder decoder = new BASE64Decoder();
// String ipAddr ="";
try {
File file = new File(PreReadUploadConfig.getUploadPath());
if(!file.exists()){
file.mkdirs();
}
// ipAddr = getIpAddr(request);
FileOutputStream write = new FileOutputStream(PreReadUploadConfig.getUploadPath()+ uuidrandom+".png");
byte[] decodeBytes = decoder.decodeBuffer(str);
write.write(decodeBytes);
write.flush();
write.close();
}catch (IOException e) {
e.printStackTrace();
}
//zxingIpAddr
//获取jar地址 例如:10.0.0.120:8089/lb/
String basePath = request.getScheme() + "://" + request.getHeader("zxingIpAddr") + request.getContextPath();//获取服务器地址
//拼接上反射地址以及图片名称
String url = basePath+"/static/" + uuidrandom+".png";
return url;
} catch (Exception e) {
e.printStackTrace();
} finally {
if (stream != null) {
stream.flush();
stream.close();
}
}
}
return null;
}
}
在这里的Base64 用的不是很好,但是暂时没有找到替换的,有办法的希望可以告诉我
这里生成完二维码之后,一般都是没有办法调用的 ,除了本地
这里需要做一个反射
路径DTO
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* @ClassName PreReadUploadConfig
* @Description ***
* @uthor ***
* @Date ***
* @Version 1.0
*/
@Component
@ConfigurationProperties(prefix="preread")
public class PreReadUploadConfig {
//上传路径
private String uploadPath;
public String getUploadPath() {
return uploadPath;
}
public void setUploadPath(String uploadPath) {
this.uploadPath = uploadPath;
}
}
这里是Springboot 项目,所以在yml文件内配置一下就好了
preread:
#文件上传目录(注意Linux和Windows上的目录结构不同)
#Linux 上路径: /usr/java/imgs/
#windows上路径: D:/test/
uploadPath: C:/test/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* @ClassName WebConfigurer
* @Description his项目
* @uthor zhangxubin
* @Date 2019/6/17 11:12
* @Version 1.0
*/
@ComponentScan
@Configuration
public class WebConfigurer extends WebMvcConfigurerAdapter {
@Autowired
PreReadUploadConfig uploadConfig;
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// /static/ 可以替换任意
registry.addResourceHandler("/static/**").addResourceLocations("file:///"+uploadConfig.getUploadPath());
}
}
这样就可以把yml文件内配置的路径反射出来
最近感觉比较乱,也写不出啥东西,就这样吧
差点忘记nginx配置了
在这里投机了,因为没找到方法可以抓取到IP以及端口号,我这里就直接写死放在头信息里面了