在前台页面有如下语句
<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如何和一个图片联系起来?
사진뿐만 아니라 다른 파일도 스트림 형태로 전송됩니다. 브라우저는 배경에서 제공하는 스트림을 그림으로 구문 분석합니다.
직설적으로 말하면 사진이 컴퓨터에 표시되는 방식은 네트워크를 통한 데이터 스트림입니다.
으아악다른 서버의 특정 사진이나 리소스를 가리키는 경우에도 마찬가지입니다. 은 웹 서버가 해당 파일을 스트림 형식으로 읽어 네트워크를 통해 전송한다는 의미입니다. 브라우저가 연결되어 있는 것은 스트림이고 스트림에 있는 파일이 무엇인지 판단할 수 있는 것은
mime type
이것은 단순한 의사 코드입니다
위 코드는 실제로 이미지를 생성하지만 파일을 하드디스크에 쓰지 않고 브라우저로 직접 보내는 코드입니다.
으아악ImageIO.write(image, "png", output)
이 문장은 실제로image
객체의 데이터를 해당 위치에 씁니다. 이 스트림이 파일 출력이면 하드 디스크에 기록되므로 이렇게 변경할 수도 있습니다.이것은 Servlet에서 파일 스트림이 전송되는 방식에 문제가 있습니다. ServletOutputStream은 HttpServletResponse.getOutputStream()을 통해 파일을 출력 스트림으로 변환합니다. 구체적인 구현 방법을 알아보려면 소스 코드를 살펴봐야 합니다.
그렇게 깊이 공부할 생각은 없으실 것 같습니다. B/S 구조에서 파일 스트림 전송의 일반적인 과정을 알고, 구체적인 코드 구현 방법과 매개변수 설정 규칙만 이해하시면 됩니다. 또한, 인증코드 생성코드를 추출하여 별도의 메소드를 작성한 후 RandomCodeController() 메소드를 호출하여 구조가 단순하고 명료하게 되도록 하는 것을 권장합니다