一、创建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对象 然后得到结果 转化成string
return 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
//597b34bea4ec4c85a775c469c84b6817
String 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参数,转成json
String 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、如果不再接收任何客户端通信,可以关闭ServerSocket
server.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、准备一个ServerSocket
ServerSocket 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();
}
}
}
}
}