2021.1.27 Обновить
Новая версия блога была обновлена, и обновленный контент немного больше, чем исходная статья, поэтому был открыт новый блог, пожалуйстакликните сюда.
1. Предпосылки
разрабатыватьApp
Взаимодействие с серверной базой данных на основеMySQL
+ роднойJDBC
+Tomcat
,не использовалDBUtils
илиJDBC
каркас, чистое дноJDBC
выполнить.
За последние несколько дней я наступил на много ям. Если преувеличить, я действительно наступил без чувств. Надеюсь, это поможет читателям меньше наступать на ямы...
2 Среда разработки
Windows10
- сервер
CentOS 7
Android Studio 3.5.1
IntelliJ IDEA 2019.02
MySQL 8.0.17
Tomcat 9.0.26
3 Подготовьте среду
в основном установитьMySQL
а такжеTomcat
, уже установленные можно пропустить.
3.1 УстановкаMySQL
Это относительно новыйMySQL
Версия.
Серверная системаCentOS
.
См. здесь для других системных установок:
CentOS
использоватьyum
Просто установите его.
3.1.1 Загрузите и установитеMySQL
sudo yum localinstall https://repo.mysql.com//mysql80-community-release-el7-1.noarch.rpm
sudo yum install mysql-community-server
3.1.2 Запустите службу и просмотрите пароль инициализации
sudo service mysqld start
sudo grep 'temporary password' /var/log/mysqld.log
3.1.3 Изменить пароль
Сначала войдите в систему с правами root:
mysql -u root -p
Введите пароль, который вы видели на предыдущем шаге, затем используйтеalter
изменить пароль:
alter mysql.user 'root'@'localhost' identified by 'password';
Обратите внимание на новую версиюMySQL
Не используйте слабые пароли, такие как:
Если появляется это сообщение, пароль слишком слабый, используйте более надежный пароль.
3.1.4 Разрешить внешний доступ
use mysql;
update user set host='%' where user='root';
Это может быть изменено в соответствии с вашими потребностями,host='%'
разрешить всеip
логин, вы также можете установить конкретныйip
, если использоватьhost='%'
В этом случае рекомендуется создать нового пользователя для настройки соответствующих разрешений.
3.1.5 Настройка брандмауэра (необязательно)
Вообще говоря, вам нужно открыть порт ответа в конфигурации брандмауэра соответствующего поставщика облака, как показано на рисунке:
Авторизованные объекты могут быть изменены в соответствии с их собственными потребностями,0.0.0.0/0
разрешить всеip
.
3.2 УстановкаTomcat
3.2.1 Загрузка и загрузка на сервер
иди первыйОфициальный сайтСкачать, загрузить файл на сервер после скачивания:
Автор используетscp
Заказ,Если вы не квалифицированы, вы можете нажать здесь, чтобы увидеть:
scp apache-tomcat-xxxx.tar.gz username@xx.xx.xx.xx:/
изменить свое имя пользователя иip
.
3.2.2 Декомпрессия
ssh
подключитесь к серверу, затем перейдите к/usr/local
и распакуйте его:
mkdir /usr/local/tomcat
mv apache-tomcat-xxxx.tar.gz /usr/local/tomcat
tar -xzvf apache-tomcat-xxx.tar.gz
3.2.3 Изменить порт по умолчанию (необязательно)
Исправлятьconf/server.xml
файл, как правило, нужно только изменить
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
середина8080
порт, вы можете изменить этот порт.
При необходимости измените его.
3.2.4 Запуск
бегатьbin
в каталогеstartup.sh
:
cd bin
./startup.sh
3.2.5 Тест
Вход через браузер:
服务器IP:端口
Если появится:
указывает на успех.
3.2.6 Запуск (необязательно)
Рекомендуется настроить запуск и изменить/etc/rc.local
файл, добавьте:
sh /usr/local/tomcat/bin/startup.sh
Это основано на вашем собственномTomcat
Изменение пути установки, указатьbin
внизstartup.sh
.
4 Создание базы данных и построение таблицы
Создайте таблицу пользователей и упростите здесь операцию, не создавая нового пользователя и не авторизуя его.
это местныйroot
Для примера входа создайте и авторизуйте пользователей в соответствии с реальной ситуацией.
4.1 Пользовательская таблица
CREATE DATABASE userinfo;
USE userinfo;
CREATE TABLE user
(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
name CHAR(30) NULL,
password CHAR(30) NULL
);
4.2 Импорт
mysql -u root -p < user.sql
Таким образом, подготовительная работа завершена, и этап кодирования официально начинается ниже.
5 Задняя часть
5.1 Создать проект
выберитеWeb Application
:
5.2 Добавить библиотеку зависимостей
создатьlib
Каталог:
добавить дваJAR
Пакет (ссылка для скачивания указана в конце статьи):
mysql-connector-java-8.0.17.jar
javax.servlet-api-4.0.1.jar
ОткрытьProject Structure
:
Modules --> + --> JARs or directories
:
Выберите только что созданныйlib
следующие дваJAR
Сумка:
отметьте иapply
:
5.3 Создание пакетов и классов
Всего 4 упаковки:
-
com.servlet
: используется для обработки запросов от внешнего интерфейса, включаяSignUp.java
,SignIn.java
-
com.util
: Основная функция — подключение к базе данных, в т.ч.DBUtils.java
-
com.entity
: класс сущности, содержащийUser.java
-
com.dao
: Класс, управляющий пользовательским классом, включаяUserDao.java
5.4 DBUtils
Класс, который подключается к базе данных, чистый нижний слойJDBC
выполнить,Обратите внимание на версию драйвера.
public class DBUtils {
private static Connection connection = null;
public static Connection getConnection()
{
try {
Class.forName("com.mysql.cj.jdbc.Driver");
String url = "jdbc:mysql://127.0.0.1:3306/数据库名字";
String usename = "账号";
String password = "密码";
connection = DriverManager.getConnection(url,usename,password);
}
catch (Exception e)
{
e.printStackTrace();
return null;
}
return connection;
}
public static void closeConnection()
{
if(connection != null)
{
try {
connection.close();
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
Основная функция - получить соединение и закрыть соединение.
String url = "jdbc:mysql://127.0.0.1:3306/数据库名字";
String usename = "账号";
String password = "密码";
Эти строки основаны на их имени пользователя, пароле, сервереip
и изменение имени библиотеки.
Обратите внимание, что оператор регистра драйвера, используемый в MySQL 8.0 и выше,:
Class.forName("com.mysql.cj.jdbc.Driver");
Старая версия:
Class.forName("com.mysql.jdbc.Driver");
5.5 User
User
Класс относительно прост, то есть три поля иGetter+Setter
.
public class User {
private int id;
private String name;
private String password;
//三个Getter与三个Setter
//...
}
5.6 UserDao
public class UserDao {
public boolean query(User user)
{
Connection connection = DBUtils.getConnection();
String sql = "select * from user where name = ? and password = ?";
try {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,user.getName());
preparedStatement.setString(2,user.getPassword());
ResultSet resultSet = preparedStatement.executeQuery();
return resultSet.next();
}
catch (SQLException e)
{
e.printStackTrace();
return false;
}
finally {
DBUtils.closeConnection();
}
}
public boolean add(User user)
{
Connection connection = DBUtils.getConnection();
String sql = "insert into user(name,password) values(?,?)";
try {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,user.getName());
preparedStatement.setString(2,user.getPassword());
preparedStatement.executeUpdate();
return preparedStatement.getUpdateCount() != 0;
}
catch (SQLException e)
{
e.printStackTrace();
return false;
}
finally {
DBUtils.closeConnection();
}
}
}
В основном это операции запроса и добавления. Если пользователь существует в операции запроса, он будет возвращен.true
, иначе возвратfalse
.
использовать в операции добавленияexecuteUpdate()
а такжеgetUpdateCount() != 0
.
Обратите внимание, что его нельзя использовать напрямую
return preparedStatement.execute();
заменить
preparedStatement.executeUpdate();
return preparedStatement.getUpdateCount() != 0;
На первый взгляд вроде бы и нет проблем.Когда автор тестировал той ночью, проблема была большая.Android
Он показывает, что регистрация не удалась, но база данных неinsert
пошел в. . .
Ах это. . .
Ну, это все еще функциональная проблема.
- Вообще говоря
select
использоватьexecuteQuery()
,executeQuery()
вернутьResultSet
, представляющий набор результатов, сохраненныйselect
Результат выполнения инструкции, сnext()
использовать -
delete
,insert
,update
использоватьexecuteUpdate()
,executeUpdate()
Возвращается целое число, представляющее количество затронутых строк, т.е.delete
,insert
,update
количество измененных строк, дляdrop
,create
Операция возвращается0
-
create
,drop
использоватьexecute()
,execute()
Возвращаемое значение похоже на это, если первый результатResultSet
объект, возвратtrue
, вернуть, если первым результатом является количество обновлений или если результата нетfalse
Итак, в этом примере
return preparedStatement.execute();
обязательно вернусьfalse
, так что это будет сторона базы данныхinsert
Захожу, но интерфейс показывает, что регистрация не удалась (давно искал эту проблему...)
5.7 SignIn
+SignUp
servlet
в сумке:
-
SingIn
класс для обработки входа, вызоваJDBC
Проверить, есть ли соответствующий пользователь в базе данных -
SignUp
класс для обработки регистрации, положитьUser
добавить в базу данных
SignIn.java
следующим образом:
@WebServlet("/SignIn")
public class SingIn extends HttpServlet {
@Override
protected void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws IOException,ServletException
{
this.doPost(httpServletRequest,httpServletResponse);
}
@Override
protected void doPost(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws IOException, ServletException
{
httpServletRequest.setCharacterEncoding("utf-8");
httpServletResponse.setCharacterEncoding("utf-8");
httpServletResponse.setContentType("text/plain;charset=utf-8");//设置相应类型为html,编码为utf-8
String name = httpServletRequest.getParameter("name");
String password = httpServletRequest.getParameter("password");
UserDao userDao = new UserDao();
User user = new User();
user.setName(name);
user.setPassword(password);
if(!userDao.query(user))//若查询失败
{
httpServletResponse.sendError(204,"query failed.");//设置204错误码与出错信息
}
}
}
прежде всего@WebServlet
Аннотация, указывающая, что это имя называетсяSignIn
изServlet
, который можно использовать для реализацииServlet
а такжеURL
сопоставление, если вы не добавите сюда эту аннотацию, вам нужноWEB-INF
в каталогеweb.xml
добавить один<servlet-mapping>
.
@WebServlet("/SignIn")
Затем установите тип ответа и кодировку:
httpServletResponse.setContentType("text/plain;charset=utf-8");//设置相应类型为html,编码为utf-8
HttpServletRequest.getParameter(String name)
метод согласноname
Получите соответствующие параметры:
String name = httpServletRequest.getParameter("name");
String password = httpServletRequest.getParameter("password");
НижеSignUp.java
:
@WebServlet("/SignUp")
public class SignUp extends HttpServlet {
@Override
protected void doGet(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws IOException,ServletException
{
this.doPost(httpServletRequest,httpServletResponse);
}
@Override
protected void doPost(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws IOException,ServletException
{
httpServletRequest.setCharacterEncoding("utf-8");
httpServletResponse.setCharacterEncoding("utf-8");//设定编码防止中文乱码
httpServletResponse.setContentType("text/plain;charset=utf-8");//设置相应类型为html,编码为utf-8
String name = httpServletRequest.getParameter("name");//根据name获取参数
String password = httpServletRequest.getParameter("password");//根据password获取参数
UserDao userDao = new UserDao();
User user = new User();
user.setName(name);
user.setPassword(password);
if(!userDao.add(user)) //若添加失败
{
httpServletResponse.sendError(204,"add failed.");//设置204错误码与出错信息
}
}
}
5.8 ДобавитьServlet
прибытьweb.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>SignIn</servlet-name>
<servlet-class>com.servlet.SingIn</servlet-class>
</servlet>
<servlet>
<servlet-name>SignUp</servlet-name>
<servlet-class>com.servlet.SignUp</servlet-class>
</servlet>
</web-app>
Поместить только что созданныйServlet
добавить вweb.xml
,существует<servlet>
добавить дочерний элемент<servlet-name>
а также<servlet-class>
:
-
<servlet-name>
даServlet
Имя рекомендуется согласовывать с именем класса -
<servlet-class>
даServlet
расположение класса
если вServlet
класс не добавлен@WebServlet("/xxxx")
аннотация, вам нужноweb.xml
добавлять:
<servlet-mapping>
<servlet-name>SignIn</servlet-name>
<url-pattern>/SignIn</url-pattern>
</servlet-mapping>
в<servlet-name>
а также<servlet>
дочерние элементы в<servlet-name>
Значения в одинаковые,<url-pattern>
это путь доступа.
5.9 Hello.html
тестовый файл
Наконец добавьтеHello.html
тестовый файл.
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Welcome</title>
</head>
<body>
Hello web.
</body>
</html>
6 Пакетный выпуск
Автор использовалIDEA
,Упаковку Eclipse смотрите здесь.
6.1 Project Structure->Artifacts->Web Application:Archive
6.2 Создайте каталог и добавьте модули
изменить имя и создатьWEB-INF
Каталоги и подкаталогиclasses
:
проверилclasses
,Добавить кModule Output
, выберите собственный веб-проект:
6.3 Добавление зависимых библиотек и других файлов
Добавить кJAR
пакет, провереноlib
Добавьте файл пакета JAR после каталога:
Затем добавьтеHello.html
а такжеweb.xml
,web.xml
нуждаться вWEB-INF
каталог,Hello.html
существуетWEB-INF
За пределами:
6.4 Упаковка
Build->Build Artifacts
:
6.5 Тест загрузки
упакованныйWAR
загрузка файла на серверTomcat
изwebapps
Под содержанием:
scp ***.war username@xxx.xxx.xxx.xxx:/usr/local/tomcat/webapps
Будьте осторожны, чтобы изменить его на свой собственныйwebapps
содержание.
Tomcat
После запуска введите в браузере
服务器IP:端口/项目/Hello.html
Я протестировал его локально для удобства:
7 Android
конец
7.1 Новое строительство
7.2 MainActivity.java
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button signin = (Button) findViewById(R.id.signin);
signin.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name = ((EditText) findViewById(R.id.etname)).getText().toString();
String password = ((EditText) findViewById(R.id.etpassword)).getText().toString();
if (UserService.signIn(name, password))
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
}
});
else {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_SHORT).show();
}
});
}
}
});
Button signup = (Button) findViewById(R.id.signup);
signup.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String name = ((EditText) findViewById(R.id.etname)).getText().toString();
String password = ((EditText) findViewById(R.id.etpassword)).getText().toString();
if (UserService.signUp(name, password))
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
}
});
else {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(MainActivity.this, "注册失败", Toast.LENGTH_SHORT).show();
}
});
}
}
});
}
}
два простыхButton
Привяжите событие, затем установите дваToast
оперативная информация.
7.3 UserService.java
public class UserService {
public static boolean signIn(String name, String password) {
MyThread myThread = new MyThread("http://本机内网IP:8080/cx/SignIn",name,password);
try
{
myThread.start();
myThread.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
return myThread.getResult();
}
public static boolean signUp(String name, String password) {
MyThread myThread = new MyThread("http://本机内网IP:8080/cx/SignUp",name,password);
try
{
myThread.start();
myThread.join();
}
catch (InterruptedException e)
{
e.printStackTrace();
}
return myThread.getResult();
}
}
class MyThread extends Thread
{
private String path;
private String name;
private String password;
private boolean result = false;
public MyThread(String path,String name,String password)
{
this.path = path;
this.name = name;
this.password = password;
}
@Override
public void run()
{
try {
URL url = new URL(path);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(8000);//设置连接超时时间
httpURLConnection.setReadTimeout(8000);//设置读取超时时间
httpURLConnection.setRequestMethod("POST");//设置请求方法,post
String data = "name=" + URLEncoder.encode(name, "utf-8") + "&password=" + URLEncoder.encode(password, "utf-8");//设置数据
httpURLConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");//设置响应类型
httpURLConnection.setRequestProperty("Content-Length", data.length() + "");//设置内容长度
httpURLConnection.setDoOutput(true);//允许输出
OutputStream outputStream = httpURLConnection.getOutputStream();
outputStream.write(data.getBytes("utf-8"));//写入数据
result = (httpURLConnection.getResponseCode() == 200);
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean getResult()
{
return result;
}
}
MyThread myThread = new MyThread("http://内网IP:8080/cx/SignUp",name,password);
MyThread myThread = new MyThread("http://内网IP:8080/cx/SignIn",name,password);
Замените эти две строки своимиip
, интранетip
может быть использованipconfig
илиifconfig
Проверьте, если порт по умолчанию изменен, порт также изменен.
Путь:
端口/web项目名/Servlet名
web
Название проекта перепечатаноWAR
устанавливается во время упаковки,Servlet
имя вweb.xml
середина<servlet>
дочерний элемент<servlet-name>
настройки, а в исходном коде@WebServlet()
Аннотации те же.
Еще одна вещь, на которую следует обратить внимание, это проблема с потоком, вам нужно открыть новый поток дляHTTP
Связь.
7.4 activity_main.xml
Интерфейсная часть страницы очень проста, всего две кнопки для функции проверки.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="用户名"
/>
<EditText
android:layout_width="300dp"
android:layout_height="60dp"
android:id="@+id/etname"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="密码"
/>
<EditText
android:layout_width="300dp"
android:layout_height="60dp"
android:id="@+id/etpassword"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="120dp"
android:layout_height="60dp"
android:text="注册"
android:id="@+id/signup"
/>
<Button
android:layout_width="120dp"
android:layout_height="60dp"
android:text="登录"
android:id="@+id/signin"
/>
</LinearLayout>
</LinearLayout>
8 тест
8.1 Регистрационный тест
Просто введите имя пользователя и пароль:
Посмотреть базу данных:
8.2 Проверка входа
9 Примечания
9.1 Имя пользователя и пароль базы данных
Имя пользователя и пароль базы данных должны быть установлены правильно, иначе будет выдано исключение, как показано ниже:
Эта ошибка также может возникать при загрузке ошибки драйвера, поэтому обязательно введитеWAR
время пакетаlib
каталог правильный иJAR
Версия пакета правильная.
Кроме того, поскольку этоJDBC
Основная реализация, обратите внимание на рукописныйSQL
Утверждения не могут быть ошибочными.
Не будь как автор:
9.2 Проблемы с сетевыми разрешениями
нуждаться вAndroidManifest.xml
Добавьте сетевые разрешения:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
9.3 Проблемы с группой безопасности/брандмауэром
Поскольку, если текущий облачный сервер обычно использует группы безопасности вместо непосредственного использования брандмауэра для настройки параметров безопасности, если вы не можете получить доступ, откройте порт в соответствующей конфигурации группы безопасности на облачном сервере.8080
порт, вообще разрешить всеip
через, источникip
настроен как0.0.0.0/0
,Например:
Если группа безопасности установлена и доступ пройден, возможно проблема с брандмауэром сервера, можете проверить.iptables
(CentOS8
использоватьfirewalld
) включен:
systemctl status iptables
Если он включен, вы можете отключить его:
systemctl stop iptables
Если он не закрыт, вы можете добавить правила порта и изменить/etc/sysconfig/iptables
:
vim /etc/sysconfig/iptables
Добавить к
-A INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT
-A RH-Firewall-1-INPUT -m state --state NEW -m tcp -p tcp --dport 8080 -j ACCEPT
перезагружатьiptables
:
systemctl restart iptables
9.4 HTTP
Меры предосторожности
из-за отAndroid P
Start, по умолчанию требует использования зашифрованных соединений, то есть использоватьHTTPS
, поэтому использованиеHTTP
соединять.
использоватьHTTP
При подключении возникает следующее исключение:
W/System.err: java.io.IOException: Cleartext HTTP traffic to **** not permitted
java.net.UnknownServiceException: CLEARTEXT communication ** not permitted by network security policy
Два решения:
- использовать
HTTPS
- изменить значение по умолчанию
AndroidManifest.xml
сделай это позволеннымHTTP
соединять
существуетres
создать новую папкуxml
, создатьnetwork_security_config.xml
файл, содержание файла следующее
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
затем вAndroidMainfest.xml
Добавить в:
<application
android:networkSecurityConfig="@xml/network_security_config"
/>
Вот и все.
Если вышеуказанный метод не работает, вы можете попробовать его непосредственно вAndroidManifest.xml
Просто добавьте фразу:
<application
android:usesCleartextTraffic="true"
/>
9.5 Проблемы с потоками
отAndroid 4.0
Вначале сеть не может работать в основном потоке.Если сеть не в порядке, она зависнет.Поэтому все операции, связанные с сетью, должны открывать новый поток и не могут работать в основном потоке.
9.6 AVD
вопрос
Я долго искал этот вопрос,HTTP
Нет проблем с подключением, нет проблем с сервером, нет проблем с базой данных, нет проблем с интерфейсным кодом, и впередStackOverflow
, найдено, чтоAVD
Проблема. . .
Просто удалите егоAPP
перезагрузиться сноваAVD
, на самом деле удалось. . .
9.8 404
По комментариям (спасибо всем, кто тут комментировал) появится404
Была проблема404
Основная причина в том, что путь доступа неверный. Вот три случая, которые нужно объяснить.
9.8.1 МестныйIDEA
доступ в
IDEA
После запуска проекта вы можете использоватьpostman
Для проверки перейдите по пути:
http://localhost:8080/SignIn
То есть, поскольку в настоящее время он не упакован, поэтому нет необходимости добавлять имя упакованного проекта.
9.8.2 МестныйTomcat
доступ
После упаковки будетxxx.war
пакетный файл, например, называемыйdemo.war
, затем используйтеpostman
Тестовый путь станет
http://localhost:8080/demo/SignIn
потому чтоTomcat
будет автоматическиdemo.war
распаковать, запуститьTomcat
позжеwebapps
Далее будет звонокdemo
папка, которая содержит упакованные файлы, путь в это время должен начинаться сdemo
в качестве эталона, такSignIn
нужно добавить передdemo
.
9.8.3 Развернуто на сервереTomcat
После развертывания на сервере с локальнымTomcat
в основном то же самое, просто поместите соответствующийlocahost
Изменение на соответствующее доменное имя или общедоступную сетьip
Вы можете, например:
http://www.example.com:8080/demo/SignIn
http://111.111.111.111:8080/demo/SignIn
10 исходный код иJAR
Сумка
10.1 JAR
Сумка
-
Драйвер MySQL 8.0.17(Обратите внимание, что это связано с вашим собственным
MySQL
версия соответствующая) - java-servlet-api-4.0.1
Другие версии могут прийтиздесьНайдите и скачайте.
10.2 Исходный код
11 Последний
Прежде всего, я хотел бы поблагодарить читателей за то, что они смогли прочитать конец. Автор действительно потратил много времени на написание этой статьи. Тем не менее, всегда будет что-то не так или непонятно для читателей. Надеюсь, у читателей есть какие-либо вопросы или другие вопросы.Их можно написать в приват автору или указать в комментариях. ,Благодарен.
12 справочных сайтов
1,CSDN-Android взаимодействует с базой данных Mysql через веб-сервер.
2,Не удалось подключиться к сети CSDN-Android высокой версии
3.CSDN-IDEA развертывает веб-проекты
4.executeQuery, executeUpdate и выполнение CSDN-PreparedStatement
5.Операция execute() CSDN-preparedstatement выполнена успешно! но возвращает ложь
6.CSDN-HttpServletResponse (1)
7.CSDN-HttpServletResponse (2)
9,StackOverflow-HttpUrlConnection
10.StackOverflow-java.net.socketexception
Если вы считаете, что статья хорошая, ставьте лайк.
В то же время приглашаем обратить внимание на публичный аккаунт WeChat: Bingling Road.