Heim  >  Artikel  >  Java  >  So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

PHPz
PHPznach vorne
2023-04-17 10:28:39651Durchsuche

    Anzeige der Ausführungsergebnisse

    Hier sind zwei einfache Testanzeigen und am Ende gibt es weitere Testbeispiele.

    Greifen Sie auf das Stammverzeichnis zu und dann auf einen Satz (Zeichenfolge) (Hinweis: Der grüne Drache ist nur mit einem Browser sichtbar, das Bild selbst gehört auch zu a (Anfrage) ist ein Bild (Binärdaten). Solange der Benutzer die Anforderungsinformationen und Antwortinformationen im Voraus festlegt, können beim Zugriff auf eine bestimmte Anforderung bestimmte Daten zurückgegeben werden. Daher habe ich eine einfache XML-Datei zum Konfigurieren dieser Informationen entworfen. Die Verwendung der XML-Konfigurationsdatei kann keine hierarchischen Informationen ausdrücken und kann nur auf einfache Konfigurationsanforderungen angewendet werden.

    Ein großes

    request_and_responsesSo implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java stellt viele Anfrage- und Antwortkonfigurationen dar, jeder

    request_and_response

    Knoten stellt eine Anfrage#🎜 dar 🎜#Anfrage- und Antwort

    Antwortinformationen, die die grundlegenden Informationen der Anfrage und Antwort enthalten. Die GET-Anfrage umfasst hauptsächlich: (

    methodSo implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java) Anfragemethode und (

    path

    ) Anfragepfad und Parameter. Die POST-Methodenanforderung enthält auch einen (

    param

    )-Anforderungsparameter. Die Antwort umfasst: content_type (Antwortinhaltstyp) und

    value

    (Antwortinhalt). Der Unterschied zwischen GET- und POST-Methoden besteht darin, dass der Anforderungspfad und die Anforderungsparameter der GET-Methode zusammen sind (alle im Anforderungsheader, kein Anforderungstext), während die Anforderungsparameter von POST Die Methode befindet sich im Anforderungshauptteil und es gibt eine CRLF-Trennung zwischen dem Anforderungsheader und dem Anforderungshauptteil. XML-Datei

    <?xml version="1.0" encoding="UTF-8"?>
    <request_and_responses>
    	<!-- & 需要使用转义字符 & -->
    		
    	<request_and_response>
    		<request>
    			<method>GET</method>
    			<path>/</path>
    		</request>
    		<response>
    			<content_type>application/json</content_type>
    			<value>I love you yesterday and today!</value>
    		</response>
    	</request_and_response>
    	
    	<request_and_response>
    		<request>
    			<method>GET</method>
    			<path>/login?account=123&pwd=456</path>
    		</request>
    		
    		<response>
    			<content_type>application/json</content_type>
    			<value>success</value>
    		</response>
    	</request_and_response>
    	
    	<request_and_response>
    		<request>
    			<method>GET</method>
    			<path>/query/龙</path>
    		</request>
    		<response>
    			<content_type>application/json</content_type>
    			<value>龙是中国等东亚国家古代神话传说生活于海中的神异生物。</value>
    		</response>
    	</request_and_response>
    	
    	<request_and_response>
    		<request>
    			<method>POST</method>
    			<path>/login</path>
    			<param>account=123&pwd=456</param>
    		</request>
    		
    		<response>
    			<content_type>application/json</content_type>
    			<value>{"result":success}</value>
    		</response>
    	</request_and_response>
    	
    	
    	<request_and_response>
    		<request>
    			<method>POST</method>
    			<path>/login</path>
    			<param>workId=12345</param>
    		</request>
    		
    		<response>
    			<content_type>application/json</content_type>
    			<value>{"result":"success", "data":{"name":"李工", "sex":"男", "age":35}}</value>
    		</response> 
    	</request_and_response>
    	
    	
    	<request_and_response>
    		<request>
    			<method>GET</method>
    			<path>/pictures/husky.jpeg</path>
    		</request>
    		
    		<response>
    			<content_type>image/jpeg</content_type>
    			<value>D:/DB/husky.jpeg</value>
    		</response> 
    	</request_and_response>
    	
    	<!-- 浏览器访问时的图标 -->
    	<request_and_response>
    		<request>
    			<method>GET</method>
    			<path>/favicon.ico</path>
    		</request>
    		
    		<response>
    			<content_type>image/webp</content_type>
    			<value>D:/DB/favicon.ico</value>
    		</response> 
    	</request_and_response>
    	
    </request_and_responses>
    XML-zugeordnete Entitätsklasse Die Informationen in XML werden in den Speicher eingelesen und zum Kapseln wird eine Entitätsklasse verwendet Information.
    package com.dragon;
    
    public class RequestAndResponse {
    	private String method;
    	private String path;
    	private String param;
    	private String content_type;
    	private String value;
    	
    	public String getMethod() {
    		return method;
    	}
    	public void setMethod(String method) {
    		this.method = method;
    	}
    	public String getPath() {
    		return path;
    	}
    	public void setPath(String path) {
    		this.path = path;
    	}
    	public String getParam() {
    		return param;
    	}
    	public void setParam(String param) {
    		this.param = param;
    	}
    	public String getContent_type() {
    		return content_type;
    	}
    	public void setContent_type(String content_type) {
    		this.content_type = content_type;
    	}
    	public String getValue() {
    		return value;
    	}
    	public void setValue(String value) {
    		this.value = value;
    	}
    	
    	@Override
    	public String toString() {
    		return "RequestAndResponse [method=" + method + ", path=" + path + ", param=" + param + ", content_type="
    				+ content_type + ", value=" + value + "]";
    	}
    }
    XML-Datei-Parser-KlasseVerwenden Sie eine Klasse, um XML-Dateien speziell in Java-Objekte zu analysieren, und verwenden Sie dann eine Listensammlung, um alle Objekte zu speichern. Hinweis: Ich bin nicht sehr gut im Benennen, es ist etwas zu lang, also begnüge dich einfach damit! Ha ha.

    Hinweis: Hier wird ein JAR-Paket für die XML-Analyse verwendet: dom4j.

    package com.dragon;
    
    import java.io.File;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    
    /**
     * 解析 xml 文件中配置的用户请求和响应数据。
     * */
    public class RequestAndResponseResolver {
    	private static final String method = "method";
    	private static final String path = "path";
    	private static final String param = "param";
    	private static final String content_type = "content_type";
    	private static final String value = "value";
    	
    	public static List<RequestAndResponse> listRequestAndResponse(String filePath) throws DocumentException{
    		File file = new File(filePath); 
    		SAXReader reader = new SAXReader();
    		Document doc = reader.read(file);
    		
    		Element root = doc.getRootElement();
    		//获取根元素下面所有的子元素,利用迭代器方式
    		Iterator<?> it = root.elementIterator();
    		
    		List<RequestAndResponse> requestAndResponses = new ArrayList<>();
    		while (it.hasNext()) {
    			//取出元素request_and_response
    			Element e = (Element)it.next();
    			//依次遍历每一个 request_and_response,获取相应的信息
    			Element request = e.element("request");
    			Element response = e.element("response");
    			
    			RequestAndResponse requestAndResponse = new RequestAndResponse();
    			requestAndResponse.setMethod(request.elementText(method));
    			requestAndResponse.setPath(request.elementText(path));
    			requestAndResponse.setParam(request.elementText(param));   //GET 方式,这个属性为 null
    			requestAndResponse.setContent_type(response.elementText(content_type));
    			requestAndResponse.setValue(response.elementText(value));
    			
    			requestAndResponses.add(requestAndResponse);
    		}
    		
    		return requestAndResponses;
    	}
    }
    Der Teil, der Anfragen empfängt und verarbeitet

    Das Folgende ist eine Einführung in den Teil, der Socket zum Empfangen und Verarbeiten von Anfragen verwendet.
    Das hier erforderliche Wissen ist im Grunde das gleiche wie bei der Verwendung von Socket. Der einzige Unterschied besteht in der Verarbeitung des Inhalts selbst, da der Inhalt selbst Daten und Nicht-Datenteile enthält. (Aus der Perspektive von HTTP können Sie nur den Datenteil sehen.)
    Die Verwendung der Socket-Programmierung bedeutet einfach, einen Port abzuhören und ihn zu verarbeiten, sobald eine Verbindung hergestellt wird. (Hier wird traditionelles BIO verwendet, ich kenne den NIO-Teil nicht.)

    Meine Verarbeitung hier besteht darin, einen Thread-Pool für die Verarbeitung zu verwenden, und jede Verbindung verwendet einen Thread für die Verarbeitung. Den vollständigen Code dieser Klasse (

    Server
    Klasse) finden Sie unten.
    	public void receive() {
    		//使用线程池处理请求
    		ExecutorService pool = Executors.newFixedThreadPool(THREAD_NUMBER);
    		
    		while (true) {
    			try {
    				Socket connection = server.accept();
    				pool.submit(new UserConnection(connection));
    			} catch (IOException e) {
    				System.out.println(this.getDate()+" 用户连接断开");
    				e.printStackTrace();
    			}
    		}
    	}

    Code zum Empfangen von Anfragen: Serverklasse

    package com.dragon;
    
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    
    public class Server {
    	private static final int THREAD_NUMBER = 10;
    	private ServerSocket server;
    	private int port;
    	
    	public Server(int port) {
    		this.port = port;
    	}
    	
    	//启动服务。
    	public void start() {
    		try {
    			server = new ServerSocket(port);
    			System.out.println(this.getDate()+" 服务启动!");
    			this.receive();
    		} catch (IOException e) {
    			System.out.println(this.getDate()+" 服务启动失败!");
    			e.printStackTrace();
    		}
    	}
    	
    	public void receive() {
    		//使用线程池处理请求
    		ExecutorService pool = Executors.newFixedThreadPool(THREAD_NUMBER);
    		
    		while (true) {
    			try {
    				Socket connection = server.accept();
    				pool.submit(new UserConnection(connection));
    			} catch (IOException e) {
    				System.out.println(this.getDate()+" 用户连接断开");
    				e.printStackTrace();
    			}
    		}
    	}
    	
    	
    	
    	private String getDate() {
    		String format = "yyyy-MM-dd HH:mm:ss";
    		Date now = new Date();
    		SimpleDateFormat dateFormat = new SimpleDateFormat(format);
    		return dateFormat.format(now);
    	}
    }

    HTTP-Anfragenachricht ist ein binärer Datenstrom von der TCP-Ebene (das Netzwerk ist geschichtet), also wir kann TCP direkt verwenden, um diesen Stream zu empfangen, Da das Parsen von Nachrichten mit Binärdaten (z. B. Datei-Uploads) komplizierter ist und ich nicht weiß, wie das geht, teste ich hier einfach eine einfache Lösung, die das macht Enthält keine binäre Dateianforderung. )Hinweis: Da die spezifische Analyse ebenfalls sehr kompliziert ist, betrifft sie die Struktur der HTTP-Nachricht. Wenn jedoch kein Datei-Upload erforderlich ist, besteht die gesamte Nachricht aus einigen Zeichendaten, sodass dies möglich ist sofort gelesen werden. Rufen Sie alle Anforderungsnachrichten ab, konvertieren Sie sie in Zeichenfolgen und verwenden Sie die Zeichenfolgen zum Parsen.

    in = connection.getInputStream();
    out = connection.getOutputStream();
    			
    //这个数字是随便设置的,因为要一次性读取整个请求报文,不能太小。(但是其实这个也很大了)
    byte[] b = new byte[5*1024];
    BufferedInputStream input = new BufferedInputStream(in);
    int count = input.read(b);
    String requestMessage = new String(b, 0, count);
    System.out.println("====================报文分隔符上界===================");
    System.out.println(requestMessage);
    System.out.println("====================报文分隔符下界===================");

    Verarbeitungsanforderungscode: UserConnection-Klasse

    Anforderungs- und Antwortinformationsinitialisierung

    Beschreibung: Verwenden Sie den statischen Initialisierungsblock, um Informationen zu initialisieren. Lesen Sie die vom Benutzer vorab konfigurierten XML-Informationen in den Speicher. Dieser Teil wurde bereits erwähnt.

    // 初始化配置好的信息
    	static {
    		try {
    			requestAndResponses = RequestAndResponseResolver.listRequestAndResponse("./src/com/dragon/request_and_response.xml");
    		} catch (DocumentException e) {
    			e.printStackTrace();
    		}
    	}

    Anfragebearbeitung und Erhalt von Antwortinformationen
    Da es sich um einen
    simulierten Anruf

    handelt, konzentriere ich mich hauptsächlich auf die drei in der Anforderungsheader Teildaten: Anforderungsmethode (Methode), Anforderungspfad (Pfad), Anforderungsparameter (Param) . Die GET-Methode und die POST-Methode werden separat verarbeitet. Der Unterschied zwischen GET und POST wird oben kurz vorgestellt (er ist jedoch nicht detailliert genug, Sie können sich zum Verständnis auf andere Informationen im Internet beziehen).

    Wenn es sich um die GET-Methode handelt, nehmen Sie über diesen Code den Inhaltstyp (Rückgabewertdatentyp) und den Wert (Rückgabewertdaten) im RequestAndResponse-Objekt heraus und weisen Sie sie den lokalen Variablen Inhaltstyp und Wert zu .

    if ("GET".compareTo(method) == 0) {
    	for (RequestAndResponse r : requestAndResponses) {
    		//这里需要对 get 方式时的请求进行解码,因为一些非 ASCII 码字符会被编码,比如汉字。
    		path = URLDecoder.decode(path, ENCODE);
    		if (r.getMethod().equals(method) && r.getPath().equals(path)) {
    			content_type = r.getContent_type();
    			value = r.getValue();
    			break;
    		}
    	}
    } else {
    	//POST 方式,请求参数是在请求体中的,请求头和请求体中间有一个换行符。
    	String param = requestMessage.substring(requestMessage.lastIndexOf(CRLF) + 2); //这里是不包括 CRLF 的两个字符的。
    	for (RequestAndResponse r : requestAndResponses) {                 //因为这个get方式的 参数为空,所以这里必须是 param 在前。
    		if (r.getMethod().equals(method) && r.getPath().equals(path) && param.equals(r.getParam())) {
    			content_type = r.getContent_type();
    			value = r.getValue();
    			break;
    		}
    	}
    }

    这里介绍一个知识:URL 中的字符是特定的,不允许中文等字符的出现,所以发送请求时会对中文等字符进行编码,如果直接使用 equals 方法的,当然不会相等了,所以需要先对数据进行解码,然后再调用 equals 方法进行处理。这个是我们平时广泛使用 的东西,有时候使用浏览器可以看到带很多奇怪字符 URL,它们都是被处理过的。

    举一个简单的例子:

    String str = "我爱你";
    String en_str = java.net.URLEncoder.encode(str, "UTF-8");
    String de_str = java.net.URLDecoder.decode(en_str, "UTF-8");
    System.out.println("编码字符:" + en_str);
    System.out.println("解码字符:" + de_str);

    So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

    注意:这里有一个特殊的情况,如果发起了没有配置的请求方法和路径,那么程序会出错。所以,这里的 content_type 和 value 有一个默认的值,而且非常有趣!

    So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

    执行响应 响应信息主要关注几点:响应信息长度(Content-Length)(按字节数计算)、响应内容类型(Content-Type)。

    虽然发送的请求里不能带二进制文件,但是响应信息是可以返回文件的,而且使用 Content-Length (一次性发送),不使用 Chunked 分块发送(这里我还不太明白,而且只是模拟,应该使用一些简单的小文件。)。

    下面是区分响应类型为 json (字符串) 还是 文件(二进制数据) 的代码:

    如果是字符串,则 value 的值是字符串的值,如果是文件,则 value 的值为一个具体的本地路径。(不应该使用网络图片,即使修改程序可以做到也没有必要,因为这样就需要依赖网络了。)

    	//这里我只处理字符串类和文件类两种响应体
    	//响应体
    	int len = 0;
    	String responseBody = null;   //响应值是 json 数据
    	File file = null; //响应值是 文件
    	if (content_type.equals("application/json")) {  //如果是 json 数据,否则就是 文件类数据(图片、文档或其它文件)
    		 responseBody = value;
    		 len = responseBody.getBytes().length;   //响应体的字节数,注意是字节数!
    	} else {
    		 file = new File(value);
    		 len = (int) file.length();
    	}

    然后就可以准备发送响应数据了,下面是发送响应的代码,注意报文的具体结构。

    	//响应头
    	responseHeader.append("HTTP/1.1").append(BLANK);
    	responseHeader.append(200).append(BLANK);
    	responseHeader.append("OK").append(CRLF);
    	responseHeader.append("Server:"+"CrazyDragon").append(CRLF);
    	responseHeader.append("Date:").append(BLANK).append(date).append(CRLF);
    	responseHeader.append("Content-Type:").append(BLANK).append(content_type).append(CRLF);
    	responseHeader.append("Content-Length:").append(BLANK).append(len).append(CRLF);
    	responseHeader.append(CRLF);
    	
    	//如果 字符串变量 responseBody 不为空,则说明返回值是 json 数据(字符串)
    	//否则就是文件类的流了。
    	if (responseBody != null) {
    		String response = responseHeader.toString() + responseBody;
    		out.write(response.getBytes("UTF-8"));    
    	} else {
    		out.write(responseHeader.toString().getBytes("UTF-8"));  
    		
    		int hasRead = 0;
    		byte[] data = new byte[4*1024];
    		try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
    			while ((hasRead = inputStream.read(data)) != -1) {
    				out.write(data, 0, hasRead);
    			}
    		}
    	}
    	out.flush();   //必要的刷新流操作。

    User Connection 的完整代码:

    package com.dragon;
    
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.URLDecoder;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    import java.util.Locale;
    import java.util.TimeZone;
    
    import org.dom4j.DocumentException;
    
    public class UserConnection implements Runnable{
    	private static final String BLANK = " ";
    	private static final String CRLF = "\r\n"; //换行符,不能写反了!
    	private static final String ENCODE = "UTF-8";
    	private static final String default_content_type = "application/json";   //当任何匹配路径都没有时。
    	private static final String default_value = "404 NOT FOUND!\n没有找到你配置的请求!";
    	
    	
    	private static List requestAndResponses;
    	private Socket connection;
    	
    	
    	// 初始化配置好的信息
    	static {
    		try {
    			requestAndResponses = RequestAndResponseResolver.listRequestAndResponse("./src/com/dragon/request_and_response.xml");
    		} catch (DocumentException e) {
    			e.printStackTrace();
    		}
    	}
    	
    	
    	
    	public UserConnection(Socket connection) {
    		this.connection = connection;
    	}
    	
    	@Override
    	public void run() {
    		InputStream in = null;
    		OutputStream out = null;
    		try {
    			in = connection.getInputStream();
    			out = connection.getOutputStream();
    			
    			//这个数字是随便设置的,因为要一次性读取整个请求报文,不能太小。(但是其实这个也很大了)
    			byte[] b = new byte[5*1024];
    			BufferedInputStream input = new BufferedInputStream(in);
    			int count = input.read(b);
    			String requestMessage = new String(b, 0, count);
    			System.out.println("====================报文分隔符上界===================");
    			System.out.println(requestMessage);
    			System.out.println("====================报文分隔符下界===================");
    
    			//以第一个 换行符 CRLF 为界限取出 请求路径和请求参数
    			String requestLine = requestMessage.substring(0, requestMessage.indexOf(CRLF));
    			String[] line = requestLine.split("\\s");
    			String method = line[0];  //考虑大小写。
    			String path = line[1];  
    			//这个数组是有三个元素,最后一个是 协议的版本,这里不需要,就不处理了。
    			String content_type = default_content_type;
    			String value = default_value;
    			if ("GET".compareTo(method) == 0) {
    			//	System.out.println("请求方式:" + method + " 请求路径(含参数):" + path);
    				for (RequestAndResponse r : requestAndResponses) {
    					//这里需要对 get 方式时的请求进行解码,因为一些非 ASCII 码字符会被编码,比如汉字。
    					path = URLDecoder.decode(path, ENCODE);
    					if (r.getMethod().equals(method) && r.getPath().equals(path)) {
    						content_type = r.getContent_type();
    						value = r.getValue();
    						break;
    					}
    				}
    			} else {
    				//POST 方式,请求参数是在请求体中的,请求头和请求体中间有一个换行符。
    				String param = requestMessage.substring(requestMessage.lastIndexOf(CRLF) + 2); //这里是不包括 CRLF 的两个字符的。
    				for (RequestAndResponse r : requestAndResponses) {                 //因为这个get方式的 参数为空,所以这里必须是 param 在前。
    					if (r.getMethod().equals(method) && r.getPath().equals(path) && param.equals(r.getParam())) {
    						content_type = r.getContent_type();
    						value = r.getValue();
    						System.out.println(content_type+" "+value);
    						break;
    					}
    				}
    			}
    		
    			StringBuilder responseHeader = new StringBuilder();
    			String date = this.getDate();
    			
    			
    			//这里我只处理字符串类和文件类两种响应体
    			//响应体
    			int len = 0;
    			String responseBody = null;   //响应值是 json 数据
    			File file = null; //响应值是 文件
    			if (content_type.equals("application/json")) {  //如果是 json 数据,否则就是 文件类数据(图片、文档或其它文件)
    				 responseBody = value;
    				 len = responseBody.getBytes().length;   //响应体的字节数,注意是字节数!
    			} else {
    				 file = new File(value);
    				 len = (int) file.length();
    			}
    			
    			//响应头
    			responseHeader.append("HTTP/1.1").append(BLANK);
    			responseHeader.append(200).append(BLANK);
    			responseHeader.append("OK").append(CRLF);
    			responseHeader.append("Server:"+"CrazyDragon").append(CRLF);
    			responseHeader.append("Date:").append(BLANK).append(date).append(CRLF);
    			responseHeader.append("Content-Type:").append(BLANK).append(content_type).append(CRLF);
    			responseHeader.append("Content-Length:").append(BLANK).append(len).append(CRLF);
    			responseHeader.append(CRLF);
    			
    			//如果 字符串变量 responseBody 不为空,则说明返回值是 json 数据(字符串)
    			//否则就是文件类的流了。
    			if (responseBody != null) {
    				String response = responseHeader.toString() + responseBody;
    				out.write(response.getBytes("UTF-8"));    
    			} else {
    				out.write(responseHeader.toString().getBytes("UTF-8"));  
    				
    				int hasRead = 0;
    				byte[] data = new byte[4*1024];
    				try (BufferedInputStream inputStream = new BufferedInputStream(new FileInputStream(file))) {
    					while ((hasRead = inputStream.read(data)) != -1) {
    						out.write(data, 0, hasRead);
    					}
    				}
    			}
    			out.flush();   //必要的刷新流操作。
    		} catch (IOException e) {
    			e.printStackTrace();
    		} finally {
    			try {
    				if (in != null)
    					in.close();
    			} catch (IOException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    	
    	private String getDate() {
    		Date date = new Date();
    		SimpleDateFormat format = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss 'GMT'", Locale.CHINA);
    		format.setTimeZone(TimeZone.getTimeZone("GMT")); // 设置时区为GMT  
    		return format.format(date);
    	}
    }

    主程序类:Main

    package com.dragon;
    
    public class Main {
    	public static void main(String[] args) {
    		Server server = new Server(9000);
    		server.start();		
    	}
    }

    更多的测试示例

    请求方式:GET 请求路径和参数:/query/龙 预期的响应类型:application/json 预期的响应值:龙是中国等东亚国家古代神话传说生活于海中的神异生物。 测试结果:

    So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

    请求方式:GET 请求路径和参数:/login?account=123&pwd=456 预期的响应类型:application/json 预期的响应值:success 测试结果:

    So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

    请求方式:GET 请求路径和参数:/pictures/husky.jpeg 预期的响应类型:image/jpeg 预期的响应值:一张图片(地址为:D:/DB/husky.jpeg)

    请求方式:POST 请求路径:/login 请求参数:account=123&pwd=456 预期的响应类型:application/json 预期的响应值:{“result”:success} 测试结果:

    So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

    注:这是使用 HttpClient 发送的 POST 请求。

    So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

    接收到的 POST 请求:

    So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

    接收到的 GET 请求(含中文参数): /query/龙 注意:“龙” 已经被编码了。

    So implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java

    Das obige ist der detaillierte Inhalt vonSo implementieren Sie einen HttpServer-simulierten Front-End-Schnittstellenaufruf in Java. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:yisu.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen