在前台页面有如下语句
<img onclick="this.src='/ran/random?random='+Math.random()" alt="验证码,点击图片更换" src="/ran/random?random=0.2868249340216069" width="86" height="40">
其中src 指向的地址不是一个img文件,而是一个转到SpringMVC的类中方法
src="/ran/random?random=0.2868249340216069"
方法如下:
@Controller
public class RandomCodeController {
@RequestMapping(value={"/ran/random"})
public void genericRandomCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setHeader("Cache-Control", "private,no-cache,no-store");
response.setContentType("image/png");
HttpSession session = request.getSession();
int width = 85;
int height = 28;
BufferedImage image = new BufferedImage(width, height, 2);
Graphics2D g = image.createGraphics();
g.setComposite(AlphaComposite.getInstance(3, 1.0f));
Random random = new Random();
g.setColor(new Color(231, 231, 231));
g.fillRect(0, 0, width, height);
g.setFont(new Font("Microsoft YaHei", 2, 24));
String sRand = "";
for (int responseOutputStream = 0; responseOutputStream < 4; ++responseOutputStream) {
String rand = String.valueOf(random.nextInt(10));
sRand = sRand + rand;
g.setColor(new Color(121, 143, 96));
g.drawString(rand, 13 * responseOutputStream + 16, 23);
}
session.setAttribute("COMMON_RAND_CODE", (Object)sRand);
g.dispose();
ServletOutputStream var12 = response.getOutputStream();
ImageIO.write((RenderedImage)image, "png", (OutputStream)var12);
var12.close();
}
}
所以其实这个src相联系的是一个ServletOutputStream
这个地方我不太理解
ServletOutputStream如何和一个图片联系起来?
高洛峰2017-04-18 10:35:36
직설적으로 말하면 사진이 컴퓨터에 표시되는 방식은 네트워크를 통한 데이터 스트림입니다.
다른 서버의 특정 사진이나 리소스를 가리키는 경우에도 마찬가지입니다. 은 웹 서버가 해당 파일을 스트림 형식으로 읽어 네트워크를 통해 전송한다는 의미입니다. 브라우저가 연결되어 있는 것은 스트림이고 스트림에 있는 파일이 무엇인지 판단할 수 있는 것은 mime type
이것은 단순한 의사 코드입니다
위 코드는 실제로 이미지를 생성하지만 파일을 하드디스크에 쓰지 않고 브라우저로 직접 보내는 코드입니다. ImageIO.write(image, "png", output)
이 문장은 실제로 image
객체의 데이터를 해당 위치에 씁니다. 이 스트림이 파일 출력이면 하드 디스크에 기록되므로 이렇게 변경할 수도 있습니다.
怪我咯2017-04-18 10:35:36
이것은 Servlet에서 파일 스트림이 전송되는 방식에 문제가 있습니다. ServletOutputStream은 HttpServletResponse.getOutputStream()을 통해 파일을 출력 스트림으로 변환합니다. 구체적인 구현 방법을 알아보려면 소스 코드를 살펴봐야 합니다.
그렇게 깊이 공부할 생각은 없으실 것 같습니다. B/S 구조에서 파일 스트림 전송의 일반적인 과정을 알고, 구체적인 코드 구현 방법과 매개변수 설정 규칙만 이해하시면 됩니다. 또한, 인증코드 생성코드를 추출하여 별도의 메소드를 작성한 후 RandomCodeController() 메소드를 호출하여 구조가 단순하고 명료하게 되도록 하는 것을 권장합니다