一、创建web项目
1、打开idea软件,点击界面上的Create New Project
2、进入如下界面。选中 java Enterprise,配置jdk,tomcat,勾选Web Application案例,注意勾选生成web.xml文件



3、指定项目的名称及项目文件的保存地址
4、创建成功
5、创建class文件和lib文件夹 点击项目的WEF-INF文件夹 ,右键,New → Directory 创建两个文件夹,classes(用来存放编译后输出的class文件) 和 lib(用于存放第三方jar包)
6、配置classes文件夹路径 File → 选择 Project Structure → 选择 Module → 选择Paths →
选择 “Use module compile output path” ->
将Output path和Test output path都选择刚刚创建的classes文件夹。

7、配置lib文件夹路径 点击Paths旁边的Dependencies 点击右边的”+”号 → 选择”Jars or Directories” -> 将Output path和Test output path都选择刚刚创建的classes文件夹 → 选择”Jar Directory” 然后一路OK就行了.
选择刚刚创建的lib文件夹
二、tomcat项目部署
1.配置tomcat 点击Run ,选择Edit Configurations.

点击右上角的三角形,运行
三、创建servlet
src–>New–>Create New Servlet

servlet中简单代码
/*** 通过urlPatterns指定映射地址或者在web.xml文件中配置*/@WebServlet(name = "helloServlet",urlPatterns = {"/hello"})public class HelloServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {}protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {System.out.println("hello serlvet");request.getRequestDispatcher("/index.jsp").forward(request,response);}}
3.测试 运行tomcat访问测试:http://localhost:8080/hello
四、页面图片准备
1.同一放在web文件夹下 格式如下 
2.lib的导入 
3.代码实现
public class Robot {private String url;private String apiKey;private String userId;public Robot() {}public Robot(String url, String apiKey) {this.url = url;this.apiKey = apiKey;}public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public String getApiKey() {return apiKey;}public void setApiKey(String apiKey) {this.apiKey = apiKey;}public String getUserId() {return userId;}public void setUserId(String userId) {this.userId = userId;}//处理请求信息private String before(String msg) {//请求参数格式为 json/*** reqType; 输入类型:0-文本(默认)、1-图片、2-音频* perception 输入信息* userInfo 用户参数* inputText 文本信息* selfInfo 客户端属性* location 地理位置信息* city 所在城市* province 省份* street 街道* apiKey 机器人标识* userId 用户唯一标识** */return "{'reqType':0,'" +"perception':{'inputText':{'text':" + msg + "}," +"'selfInfo':{'location':{'city':\"北京\",'province':\"北京\",'street':\"信息路\"}}}," +"'userInfo':{'apiKey':" + this.getApiKey() + ",'userId':'" + this.getUserId() + "'}}";}//聊天public String Chat(String msg) {//JSON字符串转JSONObject对象JSONObject jsonObject = JSONUtil.parseObj(before(msg));//Http请求类用于构建Http请求并同步获取结果,此类通过CookieManager持有域名对应的Cookie值,再次请求时会自动附带Cookie信息//Rest模式,此时body需要传入一个JSON或者XML字符串,Hutool会自动绑定其对应的Content-Type//传入路径与我们传入的JSONObject对象,获取请求响应的结果String result2 = HttpRequest.post(this.getUrl()).body(jsonObject.toString()).timeout(20000).execute().body();//JSON字符串转JSONObject对象 然后得到结果 转化成stringreturn JSONUtil.parseObj(result2).get("results").toString(); //获取返回的结果信息}}
@WebServlet(name = "sentServlet", urlPatterns = "/sent/chat")public class SentMassage extends HttpServlet {public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {response.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");response.setContentType("application/json;charset=utf-8");String inputText = request.getParameter("inputText");System.out.println(inputText);Robot robot = new Robot();robot.setUrl(Changeless.URL);robot.setApiKey(Changeless.API_ID_2);robot.setUserId(Changeless.USER_ID);JSONArray objects = JSONUtil.parseArray(robot.Chat(inputText));ArrayList<JSONObject> jsonObjectArrayLists = new ArrayList<>();for (Object jsonObject : objects) {jsonObjectArrayLists.add((JSONObject) JSONUtil.parseObj(jsonObject).get("values"));}System.out.println(jsonObjectArrayLists);/*将list集合转成json*/String result = JSONUtil.parseArray(JSON.toJSONString(jsonObjectArrayLists)).toString();/*返回数据*/response.getWriter().write(result);}}
五、Java基础代码实现
public class TestRobot {public static void main(String[] args) throws Exception {Scanner sc = new Scanner(System.in);while (true) {String our = sc.nextLine();String result = getChat(our);System.out.println("机器人:" + result);}}public static String getChat(String result) throws Exception {// 请求URL//afccb0beff0d4d12a45f3d25ced655db//597b34bea4ec4c85a775c469c84b6817String url = "http://openapi.tuling123.com/openapi/api/v2";// 图灵机器人API接口 每天只能5000次调用,建议自己去申请一个,免费的:)String apiKey = "597b34bea4ec4c85a775c469c84b6817";// 请求参数Map<String, Object> paramMap = new HashMap<>();paramMap.put("reqType", "0"); // 输入类型:0-文本(默认)、1-图片、2-音频// 输入信息Map<String, Object> perception = new HashMap<>();Map<String, String> inputText = new HashMap<>();inputText.put("text", result);Map<String, Object> selfInfo = new HashMap<>();Map<String, String> location = new HashMap<>();location.put("city", "北京");location.put("province", "北京");location.put("street", "建材城西路");selfInfo.put("location", location);perception.put("inputText", inputText);perception.put("selfInfo", selfInfo);// 用户信息Map<String, String> userInfo = new HashMap<>();userInfo.put("apiKey", apiKey);userInfo.put("userId", "123456");paramMap.put("perception", perception);paramMap.put("userInfo", userInfo);// 把map参数,转成jsonString jsonData = JSONUtil.toJSON(paramMap);// System.out.println("jsonData:" + jsonData);String r2 = HttpUtil.post(url,null,jsonData);return getResult(r2, "results");}// {"intent":{"actionName":"","code":10020,"intentName":""},"results":[{"groupType":1,"resultType":"text","values":{"text":"你好"}}]}private static String getResult(String json, String key) {List<String> list = JSONUtil.getList(json, key, String.class);String result = list.get(0);String values = JSONUtil.getString(result, "values");String text = JSONUtil.getString(values, "text");return text;}}
五、客户端与服务器
15.6.4 示例一:单个客户端与服务器单次通信
需求:客户端连接服务器,连接成功后给服务发送“lalala”,服务器收到消息后,给客户端返回“欢迎登录”,客户端接收消息后,断开连接
客户端示例代码
import java.io.InputStream;import java.io.OutputStream;import java.net.Socket;public class Client {public static void main(String[] args) throws Exception {// 1、准备Socket,连接服务器,需要指定服务器的IP地址和端口号Socket socket = new Socket("127.0.0.1", 8888);// 2、获取输出流,用来发送数据给服务器OutputStream out = socket.getOutputStream();// 发送数据out.write("lalala".getBytes());//会在流末尾写入一个“流的末尾”标记,对方才能读到-1,否则对方的读取方法会一致阻塞socket.shutdownOutput();//3、获取输入流,用来接收服务器发送给该客户端的数据InputStream input = socket.getInputStream();// 接收数据byte[] data = new byte[1024];StringBuilder s = new StringBuilder();int len;while ((len = input.read(data)) != -1) {s.append(new String(data, 0, len));}System.out.println("服务器返回的消息是:" + s);//4、关闭socket,不再与服务器通信,即断开与服务器的连接//socket关闭,意味着InputStream和OutputStream也关闭了socket.close();}}
服务器端示例代码
import java.io.InputStream;import java.io.OutputStream;import java.net.ServerSocket;import java.net.Socket;public class Server {public static void main(String[] args)throws Exception {//1、准备一个ServerSocket对象,并绑定8888端口ServerSocket server = new ServerSocket(8888);System.out.println("等待连接....");//2、在8888端口监听客户端的连接,该方法是个阻塞的方法,如果没有客户端连接,将一直等待Socket socket = server.accept();System.out.println("一个客户端连接成功!!");//3、获取输入流,用来接收该客户端发送给服务器的数据InputStream input = socket.getInputStream();//接收数据byte[] data = new byte[1024];StringBuilder s = new StringBuilder();int len;while ((len = input.read(data)) != -1) {s.append(new String(data, 0, len));}System.out.println("客户端发送的消息是:" + s);//4、获取输出流,用来发送数据给该客户端OutputStream out = socket.getOutputStream();//发送数据out.write("欢迎登录".getBytes());out.flush();//5、关闭socket,不再与该客户端通信//socket关闭,意味着InputStream和OutputStream也关闭了socket.close();//6、如果不再接收任何客户端通信,可以关闭ServerSocketserver.close();}}
15.6.5 示例二:多个客户端与服务器之间的多次通信
通常情况下,服务器不应该只接受一个客户端请求,而应该不断地接受来自客户端的所有请求,所以Java程序通常会通过循环,不断地调用ServerSocket的accept()方法。
如果服务器端要“同时”处理多个客户端的请求,因此服务器端需要为每一个客户端单独分配一个线程来处理,否则无法实现“同时”。
咱们之前学习IO流的时候,提到过装饰者设计模式,该设计使得不管底层IO流是怎样的节点流:文件流也好,网络Socket产生的流也好,程序都可以将其包装成处理流,甚至可以多层包装,从而提供更多方便的处理。
案例需求:多个客户端连接服务器,并进行多次通信
- 每一个客户端连接成功后,从键盘输入英文单词或中国成语,并发送给服务器
- 服务器收到客户端的消息后,把词语“反转”后返回给客户端
- 客户端接收服务器返回的“词语”,打印显示
- 当客户端输入“stop”时断开与服务器的连接
- 多个客户端可以同时给服务器发送“词语”,服务器可以“同时”处理多个客户端的请求
客户端示例代码
import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.io.PrintStream;import java.net.Socket;import java.util.Scanner;public class Client2 {public static void main(String[] args) throws Exception {// 1、准备Socket,连接服务器,需要指定服务器的IP地址和端口号Socket socket = new Socket("127.0.0.1", 8888);// 2、获取输出流,用来发送数据给服务器OutputStream out = socket.getOutputStream();PrintStream ps = new PrintStream(out);// 3、获取输入流,用来接收服务器发送给该客户端的数据InputStream input = socket.getInputStream();BufferedReader br = new BufferedReader(new InputStreamReader(input));Scanner scanner = new Scanner(System.in);while(true){System.out.println("输入发送给服务器的单词或成语:");String message = scanner.nextLine();if(message.equals("stop")){socket.shutdownOutput();break;}// 4、 发送数据ps.println(message);// 接收数据String feedback = br.readLine();System.out.println("从服务器收到的反馈是:" + feedback);}//5、关闭socket,断开与服务器的连接scanner.close();socket.close();}}
服务器端示例代码
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintStream;import java.net.ServerSocket;import java.net.Socket;public class Server2 {public static void main(String[] args) throws IOException {// 1、准备一个ServerSocketServerSocket server = new ServerSocket(8888);System.out.println("等待连接...");int count = 0;while(true){// 2、监听一个客户端的连接Socket socket = server.accept();System.out.println("第" + ++count + "个客户端"+socket.getInetAddress().getHostAddress()+"连接成功!!");ClientHandlerThread ct = new ClientHandlerThread(socket);ct.start();}//这里没有关闭server,永远监听}static class ClientHandlerThread extends Thread{private Socket socket;public ClientHandlerThread(Socket socket) {super();this.socket = socket;}public void run(){try{//(1)获取输入流,用来接收该客户端发送给服务器的数据BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));//(2)获取输出流,用来发送数据给该客户端PrintStream ps = new PrintStream(socket.getOutputStream());String str;// (3)接收数据while ((str = br.readLine()) != null) {//(4)反转StringBuilder word = new StringBuilder(str);word.reverse();//(5)返回给客户端ps.println(word);}System.out.println(socket.getInetAddress().getHostAddress()+"正常退出");}catch(Exception e){System.out.println(socket.getInetAddress().getHostAddress()+"意外退出");}finally{try {//(6)断开连接socket.close();} catch (IOException e) {e.printStackTrace();}}}}}
