How to write the header of the data returned by the Java socket as the server in the Java socket to the browser

1 question

A simple Java socket server is written in the Android app. Enter the corresponding IP and port in the browser to access the server to download the file. How does Java socket write the header information of the returned data, and the browser knows the name of the file to be downloaded?

 

 

 

 

 

2 AboutContent-Disposition

 In conventional HTTP response, Content-Disposition response header indicates that the content of the reply to show in what form, is inline form (that is part of a web page or a page), or in the attachment downloaded and saved to a local form.

 Content-disposition can actually control the user request to provide a default file name when the content is saved as a file, the file is displayed directly on the browser or the file download dialog box is popped up when accessed.

1) Format description: 

content-disposition = "Content-Disposition" ":" disposition-type *( ";" disposition-parm )  


2) Field description: Content-Disposition is the attribute name disposition-type is how to download, such as attachment is downloaded as an attachment method disposition-parm is the file name of the default save when the server sends a file to the client browser, if it is The file types supported by the browser are usually opened by default in the browser, such as txt, jpg, etc., and will be displayed directly in the browser. If you need to prompt the user to save, you must use Content-Disposition to process it. The key is to add Attachment:

3) Remarks: In this way, the browser will prompt to save or open, even if you choose to open, it will use the associated program such as Notepad to open instead of IE directly. Content-Disposition is to provide a default file name when the user wants to save the requested content as a file.

Copy the code code as follows:

@RequestMapping("/downloadTemplate")
	public byte[] downloadTemplate(HttpServletRequest request,HttpServletResponse response){
		
        String fileName = "Budget_Template.xlsx";  
        response.setContentType("application/vnd.ms-excel");  
        response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");  
        OutputStream out;
		try {
			out = response.getOutputStream();
			URL base = this.getClass().getResource(""); //先获得本类的所在位置,如/home/popeye/testjava/build/classes/net/
	        String path = new File(base.getFile(), "/template.xlsx").getCanonicalPath();
	        
			byte[] buf = new byte[1024];
			InputStream in = new FileInputStream(new File(path));  
			int tempbyte;
            while ((tempbyte = in.read(buf)) != -1) {
                out.write(buf);
            }
            out.flush();
            out.close();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		return null;
 
	}

 Obviously, this code is used in Java as a server-side spring mvc, but we are now writing the server-side code directly from Java socket, how do we encapsulate it, the direct code is as follows

"Content-Disposition: attachment; filename=" + fileName+ "\r\n"

 

 

 

 

 

3 Solution

  String line="HTTP/1.1 200 OK \r\n";
                Log.i(TAG,"line="+line);
                //sout.writeChars(line);
                sout.write(line.getBytes());//用字节传输,不能用字符,浏览器无法解析
//                String header="Content-Type: application/vnd.android.package-archive; charset=utf-8 \r\n"
                String header="Content-Type: application/octet-stream; charset=utf-8 \r\n"
                        + "Content-Disposition: attachment; filename=" + fileName+ "\r\n"
                        + "Content-length: "+file.length()+" \r\n\r\n";
                Log.i(TAG,"header="+header);
                sout.writeBytes(header);

The sout here is obtained through the socket

socket.getOutputStream()
"Content-Disposition: attachment; filename=" + fileName+ "\r\n"

Of course, the filename parameter can contain path information, but User-Agnet will ignore this information and only use the last part of the path information as the file name.
When you use this header when the response type ( Content-Type ) is application / octet-stream , it means that you do n’t want to display the content directly, but a "file download" dialog box pops up. The next step is It is up to you to decide whether to "open" or "save".

But if I need to download the apk file here , we can look at the Content-Type comparison table ( https://tool.oschina.net/commons/ ). I directly set the Content-Type to application / vnd.android.package-archive Can also

application/vnd.android.package-archive
                String header="Content-Type: application/vnd.android.package-archive; charset=utf-8 \r\n"
//                String header="Content-Type: application/octet-stream; charset=utf-8 \r\n"
                        + "Content-Disposition: attachment; filename=" + fileName+ "\r\n"
                        + "Content-length: "+file.length()+" \r\n\r\n";
                Log.i(TAG,"header="+header);
                sout.writeBytes(header);

 

 

 

 

Reference link:

https://www.jianshu.com/p/4c52cb691f54

https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers/Content-Disposition

https://tool.oschina.net/commons/

 

 

Published 1087 original articles · praised 706 · 3.15 million views

Guess you like

Origin blog.csdn.net/u011068702/article/details/105474285