Java Web
web开发
在Java中 动态web资源开发的技术统称为JavaWeb
web应用程序 可以提供浏览器访问的程序;
web应用程序编写完毕后 若想要提供给外界访问 需要一个服务器来统一管理
页面会动态的展示 “web的页面展示的效果 因人而异”
动态web的缺点
动态web的优点
web页面可以动态更新 所有用户看到的都是同一个页面
它可以和数据库交互(数据持久化 注册 商品买卖 用户交互…)
微软国内最早流行的就是ASP
在HTML中嵌入了VB的脚本 ASP+COM
在ASP开发中 基本一个页面(基本一个页面都有几千行的业务代码 页面机器混乱)
<h1>
<%
System.out.println("你好")
%>
<h1>
维护成本太高
C#
IIS
B/S 浏览器和服务器
C/S 客户端和服务器
服务器是一种被动的操作 用来处理用户的一些请求 和给用户一些响应信息
微软的ASP windows中自带的
Tomcat是Apache 软件基金会的Jakarta 项目中的一个核心项目,Tomcat 5支持最新的Servlet 2.4 和JSP 2.0 规范。因为Tomcat 技术先进、性能稳定,而且免费,,成为目前比较流行的Web 应用服务器。
Tomcat 服务器是一个免费的开放源代码的Web 应用服务器,属于轻量级应用服务器,在中小型系统和并发访问用户不是很多的场合下被普遍使用,是开发和调试JSP 程序的首选。对于一个初学者来说,可以这样认为,目前Tomcat最新版本为9.0.37**。**
Tomcat官方:https://tomcat.apache.org/
文件夹文件说明
启动 关闭Tomcat
访问测试http://localhost:8080/
可能遇到的问题
可以配置启动的端口号
可以配置主机的名称
Tomcat默认端口 8080
mysql 3306
http 80
https 443
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
可以配置主机的名称
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
网站是如何进行访问的
输入一个域名
检查本机的 C:\Windows\System32\drivers\etc\hosts配置文件下有没有这个域名映射
有 返回对应的ip地址
127.0.0.1 www.localhost.com
没有去DNS找 找到的话就返回 找不到就返回找不到
不会就先模仿
将自己写的网站 放到服务器(Tomcat)中指定的web应用的文件夹(webapps)下 就可以访问了问斩应该有的结构了
-- webapps:Tomcat服务器的web目录
--ROOT
--lhc 网站的目录名
--WEB-INF
-web.xml 网站配置文件
-classes Java程序
-lib web 应用所依赖的jar包
-index.html 默认的首页
-static
-css
-style.css
-js
-img
-....
HTTP
HTTP协议(HyperText Transfer Protocol,超文本传输协议)是因特网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准。
HTTP是一个基于TCP/IP通信协议来传递数据(HTML 文件, 图片文件, 查询结果等)。
Https
http1.0
http2.0
百度:
Request URL: https://www.baidu.com/ 请求地址
Request Method: GET //get方法 post方法
Status Code: 200 OK //状态码
Remote(远程) Address: 163.177.151.110:443
Accept:告诉浏览器 他所支持的数据类型
Accept-Encoding: 支持哪种编码格式 GBK UTF-8 GB2312 ISP8859-1
Accept-Language: 告诉浏览器它的语言环境
Cache-Control:缓冲控制
Connection:告诉浏览器 请求完成是断开还是保持连接
HOST:主机地址
百度:
Cache-Control: private //缓冲控制
Connection: keep-alive //连接
Content-Encoding: gzip
charset=utf-8 //编码
Content-Type: text/html; //类型
Accept: text/html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9 //语言
Cache-Control: max-age=0
Connection: keep-alive
Accept:告诉浏览器 他所支持的数据类型
Accept-Encoding: 支持哪种编码格式 GBK UTF-8 GB2312 ISP8859-1
Accept-Language: 告诉浏览器它的语言环境
Cache-Control:缓冲控制
Connection:告诉浏览器 请求完成是断开还是保持连接
HOST:主机地址
Refrush:告诉客户端 多久刷新一次
Location:让网页重写定位
200:请求响应成功
3**:请求重定向
4**:找不到资源
5**:服务器代码错误 500 502网关错误
当你的浏览器中地址栏输入地址并回车的一瞬间到页面能够展示回来 经历了什么?
为什么要学习这个技术
由此Maven诞生了
我们目前用来就是方便导入jar包的
Maven的核心思想 约定大于配置
Maven会规定好你该去如何去编写我们的Java代码 必须按照这个规范来
官方 https://maven.apache.org/
下载完解压即可:
电脑的所有环境最好放一起
在我们的系统环境变量中
配置如下
测试是否成功
在本地的仓库 远程仓库
建立一个本地仓库 (新建文件夹 maven-repo)
不选择要导入的maven包 直接创建一个普通的Maven项目
选择了javaweb的项目 这个只有在Web应用下才有
pom.xml是Maven的核心配置文件
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.lhcgroupId>
<artifactId>javaweb-01-mavenartifactId>
<version>1.0-SNAPSHOTversion>
<packaging>warpackaging>
<name>javaweb-01-maven Maven Webappname>
<url>http://www.example.comurl>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<maven.compiler.source>1.8maven.compiler.source>
<maven.compiler.target>1.8maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
dependencies>
<build>
<finalName>javaweb-01-mavenfinalName>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-clean-pluginartifactId>
<version>3.1.0version>
plugin>
<plugin>
<artifactId>maven-resources-pluginartifactId>
<version>3.0.2version>
plugin>
<plugin>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.0version>
plugin>
<plugin>
<artifactId>maven-surefire-pluginartifactId>
<version>2.22.1version>
plugin>
<plugin>
<artifactId>maven-war-pluginartifactId>
<version>3.2.2version>
plugin>
<plugin>
<artifactId>maven-install-pluginartifactId>
<version>2.5.2version>
plugin>
<plugin>
<artifactId>maven-deploy-pluginartifactId>
<version>2.8.2version>
plugin>
plugins>
pluginManagement>
build>
project>
maven由于他的约定大于配置 我们之后可能遇到我们写的配置文件 无法被导出或者生效的问题 解决方案
<build>
<resources>
<resource>
<directory>src/main/resourcesdirectory>
<excludes>
<exclude>**/*.propertiesexclude>
<exclude>**/*.xmlexclude>
excludes>
<filtering>truefiltering>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
resources>
build>
Maven中jar包的联系的关联图
解决方法 降级为3.6.1
配置Tomcat start.bat文件(目前不知道怎么解决)
在IDEA中全局默认配置中去配置
替换为wenbapp4.0版本和Tomcat一致
<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"
metadata-complete="true">
<display-name>Welcome to Tomcatdisplay-name>
<description>
Welcome to Tomcat
description>
web-app>
必须要的配置 :为什么会有这个问题 我们访问一个网站 需要制定一个文件夹名字
切记 下面的配置文件是你现在的项目 不是其他的
还有 一定要打开Tomcat服务 不然怎么调整也没用
还有 一定要打开Tomcat服务 不然怎么调整也没用
还有 一定要打开Tomcat服务 不然怎么调整也没用
进入官方https://mvnrepository.com/?cf_chl_captcha_tk=a48f18039660094440761e1b6d230ce6a69c55f8-1602326539-0-Afkz8Ted5KWfCo94r18BZ1Np84NIY65dJzT-JICrG8uKuvDHc7d-Vj3KkCSmvqWeivkNh-6pDMkZlW4_GZfollylgMnsz4bsA3sgmXHNuQRa89eW_4iPugscHbCD8MSdAKmS1zgUmaL5HGqMV3I0z3LK351OLOdCVvPbVQ57dGc-17W1Mg-TUEiVQS0hL5JfJi1GioiVogtA28MlXOmYAJAeGAw6_Mbew9qG38W2yGGQZ45voy_d1toUH8IgPY3h-87F-vB378PXe_xno313C-M4asXkOYRzKzn3F6pnmX8cqvQUaCqF1hLgvTocE4Q9V2AtDiXRS5Yd1pTeKOt0iXNsA1Af-5Yt3dxIBi9Mpr8CFTgcPZB–rCU7mdxI7iEq22JYDL8KU_bPEBddTMDztzk6vWvB8bKTLsVbmxb-6yvxT2sIxru83u6Y2oqpvIasLeyAz5p2z5KiwkVDRgg8V900O-OXi2MTwy1h3XXZLCcvguicxaSYruWdBepEITZNXOA_fXDA6R2dPNsnIz8myRet7ZfGvu8o5IYEiL-y64v
把实现了Servlet接口的Java程序叫做 Servlet
Servlet接口有两个默认的实现类 HttpServlet,GenericServlet
构建一个普通Maven项目 删掉里面的src目录 以后我们的学习就在这个项目里面简历moudel 这个空的工程就是Maven的主工程
guanyu Maven父子工程的理解:
父项目中会有
<modules>
<module>servlet-01module>
modules>
子项目中会有
<parent>
<artifactId>javaweb-02-servletartifactId>
<groupId>com.lhcgroupId>
<version>1.0-SNAPSHOTversion>
parent>
父项目中的java子项目可以直接使用
son extends father
Maven环境优化
编写一个Servlet程序
编写一个普通类
实现Servlet接口 我们这里直接继承HttpServlet
public class HelloServlet extends HttpServlet {
//由于get和post只是请求实现的不同的方式 可以互相调用 业务逻辑一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//ServletOutputStream outputStream = resp.getOutputStream();
PrintWriter writer = resp.getWriter();//响应流
writer.println("hello servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
编写Servlet的映射
为什么需要映射 我们写的是java程序 但是要通过浏览器访问
浏览器需要连接web服务器
所以我们需要在web服务器中注册我们写的Servlet
还需要给他一个浏览器能够访问的路径
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.lhc.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
配置Tomcat
注意配置项目发布的路径就可以了
启动测试
Servlet是由Web服务器调用
web服务器在收到浏览器请求之后 会:
一个Servlet可以指定一个映射路径(http://localhost:8080/hello)
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
一个Servlet可以指定多个映射路径(http://localhost:8080/s1/hello1 http://localhost:8080/s1/hello2 http://localhost:8080/s1/hello3 )
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello1url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello2url-pattern>
servlet-mapping>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello3url-pattern>
servlet-mapping>
一个Servlet可以指定通用映射路径(比如访问http://localhost:8080/s1/qwjkejka)
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hello/*url-pattern>
servlet-mapping>
默认请求路径(怎么访问都是hello这个servlet)
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/*url-pattern>
servlet-mapping>
指定一些后缀或者前缀等等…(比如访问http://localhost:8080/s1/dsklajdlkaj.lhc http://localhost:8080/s1/hello1/dasdasjh.lhc )*前面不能写/ 但是只要是最后是.lhc就可以映射到
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>*.lhcurl-pattern>
servlet-mapping>
优先级问题
指定了固有的映射路径优先级最高 如果找不到就会走默认的处理请求
web容器在启动的时候,它会为每个web程序都创建一个的ServletContext对象 它代表了当前web应用;
我在这个Servlet中保存的数据 可以在另外一个Servlet中拿到
设置要拿走的username数据的类
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//this.getInitParameter() 初始化参数
//this.getServletConfig() Servlet配置
//this.getServletContext();Servlet上下文
ServletContext context = this.getServletContext();
String username="林宏程";//数据
context.setAttribute("username",username);//将一个数据保存在了ServletContext 名字为username 值为 林宏程
System.out.println("hello");
}
}
设置一个获取username数据的类
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String username = (String) context.getAttribute("username");
resp.setContentType("text/html");//配置content的传输格式
resp.setCharacterEncoding("utf-8");//配置content的编码
resp.getWriter().println("名字"+username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
配置web.xml
<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"
metadata-complete="true">
<servlet>
<servlet-name>helloservlet-name>
<servlet-class>com.lhc.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>helloservlet-name>
<url-pattern>/hellourl-pattern>
servlet-mapping>
<servlet>
<servlet-name>getcservlet-name>
<servlet-class>com.lhc.servlet.GetServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>getcservlet-name>
<url-pattern>/getcurl-pattern>
servlet-mapping>
web-app>
访问的结果 需要先访问/hello 再访问/getc才能获取到username
<context-param>
<param-name>urlparam-name>
<param-value>jdbc:mysql://localhost:3306/mybatisparam-value>
context-param>
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().println(url);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
System.out.println("进入了ServletDemo04");
//RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp");//转发的请求路径
//requestDispatcher.forward(req,resp);//调用forward实现请求转发
context.getRequestDispatcher("/gp").forward(req,resp);
}
}
A B C是3个网站 A需要C的数据
请求转发过程
重定向
Properties
发现 都被打包了同一个目录下 classes 我们俗称为classpath(类路径)
但是放在java下的db.properties需要在pom.xml加入
<build>
<resources>
<resource>
<directory>src/main/resourcesdirectory>
<excludes>
<exclude>**/*.propertiesexclude>
<exclude>**/*.xmlexclude>
excludes>
<filtering>truefiltering>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>truefiltering>
resource>
resources>
build>
思路 需要一个文件流
username=lhc
password=123456
然后用InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");获取里面的流
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
Properties prop1 = new Properties();
prop1.load(is);
String user1 = prop1.getProperty("username");
String pwd1 = prop1.getProperty("password");
resp.getWriter().println("lhc_username="+user1);
resp.getWriter().println("lhc_password="+pwd1);
InputStream si = this.getServletContext().getResourceAsStream("/WEB-INF/classes/com/lhc/servlet/aa.properties");
Properties prop2 = new Properties();
prop2.load(si);
String user2 = prop2.getProperty("username");
String pwd2 = prop2.getProperty("password");
resp.getWriter().println("lt_username="+user2);
resp.getWriter().println("lt_password="+pwd2);
}
访问测试即可
响应
web服务器接收客户端的http请求 针对这个请求 分别创建一个代表请求的HttpServletRequest 代表响应的一个HttpServletResponse
负责向浏览器发送数据的方法
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
负责想浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
void setStatus(int var1);
响应的状态码
int SC_CONTINUE = 100;
int SC_SWITCHING_PROTOCOLS = 101;
int SC_OK = 200;
int SC_CREATED = 201;
int SC_ACCEPTED = 202;
int SC_NON_AUTHORITATIVE_INFORMATION = 203;
int SC_NO_CONTENT = 204;
int SC_RESET_CONTENT = 205;
int SC_PARTIAL_CONTENT = 206;
int SC_MULTIPLE_CHOICES = 300;
int SC_MOVED_PERMANENTLY = 301;
int SC_MOVED_TEMPORARILY = 302;
int SC_FOUND = 302;
int SC_SEE_OTHER = 303;
int SC_NOT_MODIFIED = 304;
int SC_USE_PROXY = 305;
int SC_TEMPORARY_REDIRECT = 307;
int SC_BAD_REQUEST = 400;
int SC_UNAUTHORIZED = 401;
int SC_PAYMENT_REQUIRED = 402;
int SC_FORBIDDEN = 403;
int SC_NOT_FOUND = 404;
int SC_METHOD_NOT_ALLOWED = 405;
int SC_NOT_ACCEPTABLE = 406;
int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
int SC_REQUEST_TIMEOUT = 408;
int SC_CONFLICT = 409;
int SC_GONE = 410;
int SC_LENGTH_REQUIRED = 411;
int SC_PRECONDITION_FAILED = 412;
int SC_REQUEST_ENTITY_TOO_LARGE = 413;
int SC_REQUEST_URI_TOO_LONG = 414;
int SC_UNSUPPORTED_MEDIA_TYPE = 415;
int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
int SC_EXPECTATION_FAILED = 417;
int SC_INTERNAL_SERVER_ERROR = 500;
int SC_NOT_IMPLEMENTED = 501;
int SC_BAD_GATEWAY = 502;
int SC_SERVICE_UNAVAILABLE = 503;
int SC_GATEWAY_TIMEOUT = 504;
int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
向浏览器输出消息(resp.getWriter().println(“lt_username=”)
下载文件
mapping不再说明
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//1. 要获取下载文件的路径
String realPath ="F:\\JAVA的学习\\6.JavaWeb\\javaweb-02-servlet\\response\\target\\classes\\a.jgp";
System.out.println("下载文件的路径"+realPath);
//2. 下载的文件名叫什么
String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
//3. 想办法让浏览器能够支持下载我们需要的东西 如果文件有中文 URLEncoder.encode()编码 否则有可能有乱码
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
//4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
//5. 创建缓冲区
int len=0;
byte[] buffer = new byte[1024];
//6. 获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//7. 将FileOutputStream流写入到buffer缓冲区
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
in.close();
out.close();
//8. 使用OutputStream将缓冲器中的数据输出到客户端
}
验证码怎么来的?
mapping不再说明
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如果让浏览器5S刷新一次
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);
//得到图片
Graphics2D g = (Graphics2D)image.getGraphics();//相当于一个笔
//设置图片的背景颜色
g.setColor(Color.white);
g.fillRect(0,0,80,20);
//给图片写数据
g.setColor(Color.blue);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20);
//告诉浏览器 这个请求用图片的方式打开
resp.setContentType("image/jpg");
//网站存在缓冲 不让浏览器缓冲
resp.setDateHeader("expires",-1);
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg",resp.getOutputStream());
}
//生成随机数
private String makeNum(){
Random random = new Random();
String num = random.nextInt(9999999) + "";
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7 - num.length(); i++) {
sb.append("0");
}
String s = sb.toString() + num;//保证num是7位 如果随机小于7位数就用0填充
return num;
}
一个web资源受到客户端请求后 他会通知客户端去访问另外一个web资源 这个过程叫重定向
常见场景
void sendRedirect(String var1) throws IOException;
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// resp.setHeader("Location","/response_war/img");
// resp.setStatus(302);//重定向代码
resp.sendRedirect("/response_war/img");//重定向
}
面试题 请你聊聊重定向和转发的区别
相同点
不同点
请求转发过程
重定向
RequestTest.java
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入了这个请求");
//处理请求
String username = req.getParameter("username");//获取前端发来的username
String password = req.getParameter("password");//获取前端发来的password
System.out.println(username+"====="+password);
//重定向的时候 一定要注意路径问题(绝对网页路径) 否则404
resp.sendRedirect("/r/success.jsp");
}
index.jsp
Hello World!
<%--这里提交的路径 需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath()}代表当前的项目--%>
success.jsp
Title
成功登入
从这里可以得出一个理解:
后台和前端的连接就是servlet mapping来连接的 index.jsp里有一个${pageContext.request.contextPath}/login
${pageContext.request.contextPath}指定当前页面 /login是通过mapping映射的/login才找到了 RequestTest.java 然后再通过RequestTest.java 处理这个请求 用resp.sendRedirect("/r/success.jsp");重定向到success.jsp 而控制台里输出 {进入了这个请求 1025993689=====1} 也说明前端的内容已经被我们后端获取到了
HttpServletRequest代表客户端的请求 用户通过Http协议访问服务器 HTTP请求中的所有信息会被封装到HttpServletRequest 通过这个HttpServletRequest的方法 获取客户端的所有信息
重定向和转发的区别
相同点
不同点
请求转发过程
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobbies");
//后台接受中文乱码的问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
System.out.println(username);
System.out.println(password);
System.out.println(hobbies);
//通过请求转发
//说明 这里的/就代表当前的web引用
req.getRequestDispatcher("/success.jsp").forward(req,resp);
resp.setCharacterEncoding("utf-8");
}
}
会话:用户打开了一个浏览器 点击了很多个超链接 访问多个web资源 关闭浏览器 这个过程可以称之为回话
有状态会话:一个同学来过教室 下次再来教室 我们会知道这个同学 曾经来过 称之为有状态会话
如何证明自己是福建工程学院的学生?
你 福建工程学院
一个网站 怎么证明你来过
客户端 服务器
cookie
session
最常见:网站登入之后 你下次不用再登入了 第二次访问直接就上去了
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Lfngq64z-1603629176227)(…/图片/image-20201017200941908.png)]
从请求中拿到cookie信息
服务器响应给客服端cookie
Cookie[] cookies = req.getCookies();//获得cookie
cookie.getName()//获得cookie中的key
cookie.getValue()//获得cookie中的value
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");//新建一个cookie
cookie.setMaxAge(24*60*60);//设置cookie的有效期
resp.addCookie//响应给客户端一个cookie
cookie 一般会保存在本地的 用户目录下appdata;
一个网站cookie是否存在上限? 聊聊细节问题
删除cookie
编码解码
//解码 这个是解决cookie的乱码
out.write(URLDecoder.decode(cookie.getValue(), "UTF-8"));
//编码 这个是解决cookie的乱码
Cookie cookie = new Cookie("name", URLEncoder.encode("林宏程", "UTF-8"));
cookie的实际使用
//保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//服务器 告诉你 你来的时间 把这个时间封装成一个 信件 你下次带来 我就知道你来了
//解决中文乱码 chrome要编码改成GBK才能解决乱码
req.setCharacterEncoding("GBK");
resp.setCharacterEncoding("GBK");
PrintWriter out = resp.getWriter();
//cookie 服务器端从客户端获取
Cookie[] cookies = req.getCookies();//这里返回数组 说明cookie可能存在多个 这里是第一次创建 所以获得的cookie肯定是空的 在第二次执行的时候会把新建的cookie赋值给这个cookies
//判断 cookie是否存在
if (cookies!=null){
//如果存在怎么办?
out.write("你上一次访问的时间是:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("lastLoginTime")){
//获取cookie中的值
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
}
}
}else{
out.write("这是你第一次访问本站");
}
//服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
//有效期为24*60*60秒 为1天
cookie.setMaxAge(24*60*60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//创建一个cookie 名字必须要和删除的名字一致
Cookie cookie = new Cookie("lastLoginTime", System.currentTimeMillis()+"");
//将cookie有效期设为0 立马过去
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
//中文数据传递
public class CookieDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决中文乱码
req.setCharacterEncoding("GBK");
resp.setCharacterEncoding("GBK");
Cookie[] cookies = req.getCookies();
PrintWriter out = resp.getWriter();
if (cookies != null) {
//如果存在怎么办?
out.write("你的名字:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("name")) {
//获取cookie中的值
//解码 这个是解决cookie的乱码
out.write(URLDecoder.decode(cookie.getValue(), "UTF-8"));
}
}
} else {
out.write("这是你第一次访问本站");
}
//编码 这个是解决cookie的乱码
Cookie cookie = new Cookie("name", URLEncoder.encode("林宏程", "UTF-8"));
resp.addCookie(cookie);
}
常用的一些方法
区别小总结:Session像是一个储藏柜 客户端需要SessionID才能拿到储藏柜里的资源 Cookie是直接把储藏柜里的资源让客户端拿走 下次来的时候直接使用这个资源
使用场景:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
//给Session中存东西
session.setAttribute("name",new Person("林宏程",24));
//获取Session的id
String sessionId = session.getId();
//判断Session是不是新建的
if (session.isNew()){
resp.getWriter().write("session创建成功,ID"+sessionId);
}else {
resp.getWriter().write("session已经存在了"+sessionId);
}
//Session创建的时候做了什么事情
// Cookie cookie = new Cookie("JSESSIONID", "71804CF271369B39C1BF1EC0280BDE16");
// resp.addCookie(cookie);
}
person对象
public class Person {
private String name;
private int age;
}
使用(创建Session在上面的 Session使用)
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到Session
HttpSession session = req.getSession();
Person person = (Person)session.getAttribute("name");
System.out.println(person.toString());
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute("name");
//手动注销session
session.invalidate();
}
<session-config>
<session-timeout>15session-timeout>
session-config>
思考 假如你用两个浏览器去访问这些网站 但是你是需要的资源是同样的
需要的导入包
<dependencies>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>2.5version>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>javax.servlet.jsp-apiartifactId>
<version>2.3.3version>
dependency>
<dependency>
<groupId>javax.servlet.jsp.jstlgroupId>
<artifactId>jstl-apiartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>taglibsgroupId>
<artifactId>standardartifactId>
<version>1.1.2version>
dependency>
dependencies>
JSP已经过时 这里的内容只需要了解 理解代码即可
Java Server page : Java服务器端页面 也和Servlet一样 用于动态Web技术
最大的特点
JSP到底怎么执行的?
代码层面没有任何问题
服务器内部工作
Tomcat中有一个work目录
IDEA中使用Tomcat的会在IDEA中Tomcat中产生一个work目录
页面转变成了Java程序
浏览器向服务器发送请求 不管访问什么资源 其实都是在访问servlet
JSP最终也会转换成一个Java类!
JSP本质就是个Servlet
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//JSP Service
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException
判断请求
内置了一些对象
final javax.servlet.jsp.PageContext pageContext; //页面上下文
final javax.servlet.ServletContext application;//applicationcontext
final javax.servlet.ServletConfig config; //conig
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page
HttpServletRequest request //请求
http.HttpServletResponse //响应
输出页面前增加的代码
response.setContentType("text/html; charset=UTF-8");//这是响应的页面类型
pageContext = _jspxFactory.getPageContext(this, request, response,
null, false, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
out = pageContext.getOut();
_jspx_out = out;
以上的这些个对象我们可以在JSP页面中直接使用
在JSP页面中 只要是Java代码 就会原封不动的输出
如果是HTML代码 就会转换成:
out.write("/r/n")
这样的格式输出到前端
任何语言都有自己的语法 JAVA中有 JSP作为java技术的一种应用 他拥有一些自己扩充的语法(了解 知道即可)
Java所有语法都支持
<%--JSP表达式
作用 用来将程序输出 输出到客户端
<%= 变量或者表达式 %>
--%>
<%= new java.util.Date()%>
<%--JSP脚本片段--%>
<%
int sum=0;
for (int i = 0; i < 100; i++) {
sum+=i;
}
out.println("sum="+sum+"");
%>
<%--在代码中嵌入HTML元素--%>
<%
for (int i = 0; i < 5; i++) {
%>
你好!<%=i %>
<%
}
%>
<%!
static {
System.out.println("Loading Servlet");
}
private int globalVar=0;
public void lhc(){
System.out.println("进入了方法lhc");
}
%>
JSP声明 会被编译到JSP生成Java的类中 其他的会被生成到_jspService方法中
在JSP 嵌入Java即可
<%%>
<%=%>
<%!%>
<%--注释--%>
<%--JSP的注释--%>
JSP的注释不会在客服端显示 HTML会
<%@ page args... %>
<%@ include File %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
Title
<%-- <%@ include %>会将两个页面合二为一 直接把代码写到_jsp.java中 --%>
<%@ include file="common/header.jsp" %>
我是主体
<%
int i=10;//因为他是直接用put.write输出 所以在这个页面不会报错 在web执行的时候 才会调用 那个时候才会报错 所以用下面的更加好
%>
<%@ include file="common/footer.jsp" %>
<%-- 拼接页面 在静态方法中调用这2个页面 --%>
<%--JSP标签 这里的路径是web--%>
我是主体
<%
int i=10;//因为这个实现是直接调用本类静态方法 所以他会直接报错(i 已经定义)
%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
我是header
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
我是footer
<%
int i=10;
%>
实际页面(没有测试 变量i调用的问题)
pageContext | 存东西 |
---|---|
Request | 存东西 |
Response | |
Session | 存东西 |
Application(ServletContext) | 存东西 |
config(ServletConfig) | |
out | |
page | 几乎不用 |
exception |
生成各自Attribute
pageContext.setAttribute("name1", "pageContext");//保存的数据只在一个页面有效
request.setAttribute("name2", "request");//保存的数据只在一次请求中有效 请求转发会携带这个参数
session.setAttribute("name3", "session");//保存的数据只在一次会话中有效 打开浏览器到关闭浏览器
application.setAttribute("name4", "application");//保存的数据只在服务器中有效 打开服务器到关闭服务器
//这里做了个小测试 如果用请求转发(pageContext.forward)到 pageDemo02.jsp request还是可以读取到的 但是如果用重定向(response.sendRedirect)这里的request就读取不到了
response.sendRedirect("pageDemo02.jsp");
pageContext.forward("pageDemo02.jsp");
//在重定向中 A到C的时候没有转发只有请求 所以丢失了request的数据了
//而请求转发中 他是A请求B B转发C C请求B B转发A (这个理解不知道是不是对的)
转到第二个页面后去查找
<%
//通过pageContext取出 我们通过寻找的方式来找
//从底层到高层(作用域) page-->request-->session-->application
//JVM 双亲委派机制:一个类使用方法找不到的时候 会不断向父类去找有没有存在这个方法 如果找不到就报异常 如果和根类名字一样会被无视 (听着高大上 其实很简单
String name1 = (String)pageContext.findAttribute("name1");
String name2 = (String)pageContext.findAttribute("name2");
String name3 = (String)pageContext.findAttribute("name3");
String name4 = (String)pageContext.findAttribute("name4");
String name5 = (String)pageContext.findAttribute("name5");//不存在
%>
<%--使用EL表达式--%>
<h1>取出的值为</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
<%-- EL表达式会自动过滤不存在的 但是这个不会--%>
<h3><%=name5%></h3>
原理图
请求转发过程
重定向
//可以设置他的作用域
pageContext.setAttribute("hello","hello",pageContext.SESSION_SCOPE);
//session.setAttribute("hello","hello"); 等价上面的代码
request 客户端向服务器发送请求 产生的数据 用户看完就没用了 比如 新闻 用户看完就没用的
session 客户端向服务器发送请求 产生的数据 用户用完 一会还有用 比如 购物车
application 客户端向服务器发送请求 产生的数据 用户用完 其他用户还可能使用 比如 QQ聊天数据
设值
jsptag1
<%--
取值
jsptag2
<%--取出参数--%>
name: <%=request.getParameter("name")%>
age: <%=request.getParameter("age")%>
JSTL标签库的使用就是为了弥补HTML标签的不足 它自定义了许多标签 可以供我们使用 标签的功能和Java代码一样
格式化标签
SQL标签
XML标签
引入对应的taglib
<%--引入JSTL核心表艰苦 我们才能使用JSTL标签--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
使用其中的方法
在Tomcat的lib包也需要引入JSTL的包 否则会报错 JSTL解析错误
if测试
<%--判断如果提交的用户名管理员 则登入成功--%>
<%--<%--%>
<%-- if(request.getParameter("username").equals("admin")){--%>
<%-- out.print("登入成功");--%>
<%-- }--%>
<%--%>--%>
<%--定义一个变量score 值为85--%>
你的成绩为优秀
你的成绩为一般
<%
ArrayList people = new ArrayList<>();
people.add(0,"张三");
people.add(1,"李四");
people.add(2,"王五");
people.add(3,"赵六");
request.setAttribute("list",people);
%>
<%--
var 每一次遍历出来的变量
item 要遍历的对象
begin 哪里开始
step 步长
end 哪里结束
--%>
这里只出来上面的遍历 下面的没出来
实体类
JavaBean有特定的写法
一般用来和数据库的字段做映射 ORM
ORM 对象关系映射
people表
id | name | age | address |
---|---|---|---|
1 | 林宏程1 | 3 | 温州 |
2 | 林宏程2 | 4 | 温州 |
3 | 林宏程3 | 5 | 温州 |
class people{
private int id;
private String name;
private int age;
private String address;
}
class A{
new people(1,"林宏程1",3,"温州")
new people(2,"林宏程1",4,"温州")
new people(3,"林宏程1",5,"温州")
}
什么MVC:model view controller 模型/视图/控制器
用户直接访问控制层 控制层就可以直接操作数据库
servlet--CRUD-->数据库
弊端 程序十分臃肿
servlet的代码中 处理请求 响应 视图跳转 处理JDBC 处理业务代码 处理逻辑代码
架构 没有什么是加一层解决不了的
程序员调用
|
JDBC
|
Mysql
接受用户的请求 (request.请求参数 Session信息…)
交给业务层处理对应的代码
控制跳转
登入---->接受用户的登入请求---->处理用户的请求(获取用户登入的参数 username password)---->交给业务层处理登入业务(判断用户名密码是否正确:事务)---->Dao层查询用户层和密码是否正确---->数据库
这里的代码无法实现 目前无法解决这个bug 显示没有导入javax.servlet.Servlet 但是实际上导入了
Filter 过滤器 用来过滤网站的数据
Filter开发步骤
导包
编写过滤器(切记是这个包)
public class CharacterEncodingFilter implements Filter{
//初始化 web服务器启动 就已经初始化了 随时等待过滤对象
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter 初始化");
}
//chain 链
/*
1.过滤中的所有代码 在过滤特定请求的时候回执行
2.必须要让过滤器继续同行
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("CharacterEncodingFilter 执行前");
chain.doFilter(request,response);//让我们的请求继续走 如果我们不写 程序到这里就被拦截停止了
System.out.println("CharacterEncodingFilter 执行后");
}
//销毁 web服务器关闭的时候 过滤会销毁
public void destroy() {
System.out.println("CharacterEncodingFilter 销毁");
}
}
web.xml配置Filter过滤器(新的版本已经更改这样了 原来是用servlet来映射的)
<filter>
<filter-name>filterfilter-name>
<filter-class>com.lhc.filter.filterfilter-class>
filter>
<filter-mapping>
<filter-name>filterfilter-name>
<url-pattern>/servlet/*url-pattern>
filter-mapping>
实现个监听器的接口:
编写一个监听器
public class OnlineCountListener implements HttpSessionListener {
//创建session监听 看你的一举一动
//一旦创建一个session 就会触发一次这个事件
public void sessionCreated(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if(onlineCount==null){
onlineCount=new Integer(1);
}else {
int count=onlineCount.intValue();
onlineCount = new Integer(count++);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
//销毁session监听
//一旦销毁一个session 就会触发一次这个事件
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext ctx = se.getSession().getServletContext();
Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");
if(onlineCount==null){
onlineCount=new Integer(0);
}else {
int count=onlineCount.intValue();
onlineCount = new Integer(count--);
}
ctx.setAttribute("OnlineCount",onlineCount);
}
}
web.xml注册监听器
<listener>
<listener-class>com.lhc.listener.OnlineCountListenerlistener-class>
listener>
看情况是否使用
package com.lhc.listener;
import java.awt.*;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class TestPanel {
public static void main(String[] args) {
Frame frame = new Frame("你好!");//新建一个窗体
Panel panel = new Panel(null);//面板
frame.setLayout(null);//设置窗体的布局
frame.setBounds(300, 300, 500, 500);
frame.setBackground(new Color(0, 0, 255));//设置背景颜色
panel.setBounds(50, 50, 300, 300);
frame.setBackground(new Color(0, 255, 0));//设置背景颜色
frame.add(panel);
frame.setVisible(true);
//监听事件
frame.addWindowListener(new WindowListener() {
public void windowOpened(WindowEvent e) {
System.out.println("打开");
}
public void windowClosing(WindowEvent e) {
System.out.println("关闭中");
System.exit(0);
}
public void windowClosed(WindowEvent e) {
System.out.println("关闭");
}
public void windowIconified(WindowEvent e) {
}
public void windowDeiconified(WindowEvent e) {
}
public void windowActivated(WindowEvent e) {
}
public void windowDeactivated(WindowEvent e) {
}
});
}
}
用户登入的时候给用户一个session(session是存在服务器里的 每个用户都能获得自己的session )
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取前端请求的参数
String username = req.getParameter("username");
if(username.equals("admin")){
//登入成功
req.getSession().setAttribute("USER_SESSION",req.getSession().getId());
resp.sendRedirect("/sys/success.jsp");
}else {
//登入失败
resp.sendRedirect("error.jsp");
}
}
注销的时候要清除用户session
错误
没有权限 用户名错误
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object user_session = req.getSession().getAttribute("USER_SESSION");
if (user_session!=null){
req.getSession().removeAttribute("USER_SESSION");
resp.sendRedirect("/login.jsp");
}else {
resp.sendRedirect("/login.jsp");
}
}
进入主页的时候 要判断用户是否登入 在过滤器中实现
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {
//ServletRequest HttpServletRequest 因为监听器的ServletRequest是没有重定向方法的 需要强转
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
if (request.getSession().getAttribute(Constant.USER_SESSION)==null){
response.sendRedirect("/error.jsp");
}
chain.doFilter(request,response);
}
设置的常量USER_SESSION
public class Constant {
public final static String USER_SESSION="USER_SESSION";
//因为这个session的ID经常被使用 我们可以把ID的key USER_SESSION 直接变成一个常量 这样每次调用直接写 constant.USER_SESSION
//而在以后维护需要更改名字的时候 可以直接在这里改 如果是每次使用创建一个 那么修改起来会非常麻烦
}
什么是JDBC: Java 连接数据库
需要的jar包支持
实验环境搭建
public static void main(String[] args) throws ClassNotFoundException, SQLException {
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&character=utf-8";
String username = "root";
String password = "123456";
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库 connection代表数据库
Connection connection = DriverManager.getConnection(url, username, password);
//3.向数据库发送sql对象 statement
Statement statement = connection.createStatement();
//4.编写sql
String sql = "select * from users";
//5.执行sql 返回一个结果集
ResultSet rs = statement.executeQuery(sql);
while (rs.next()){
System.out.println("id="+rs.getObject("id"));
System.out.println("name="+rs.getObject("name"));
System.out.println("password="+rs.getObject("password"));
System.out.println("email="+rs.getObject("email"));
System.out.println("birthday="+rs.getObject("birthday"));
}
//6.关闭连接 先创建后关闭
rs.close();
statement.close();
connection.close();
}
导入数据库依赖
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.31version>
dependency>
dependencies>
IDEA中连接数据库
JDBC固定步骤
事务
要么都成功 要么都失败
ACID原则 保证数据的安全
开启事务
事物提交 commit()
事务回滚 rollback()
关闭事务
转账
A 1000元
B 1000元
A(900)---100-->B(1100)
Junit单元测试
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
简单实用(如果要测试这个test方法 需要 新建一个main 但是用@Test注解就可以直接运行这个方法)
@Test
public void test(){
System.out.println("你好");
}
代码演示转账
package com.lhc.test;
import org.junit.Test;
import java.sql.*;
public class TestJDBC3 {
@Test
public void test() throws ClassNotFoundException, SQLException {
Connection connection = null;
try {
//解决乱码问题 useUnicode=true&characterEncoding=utf8
String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf8";
String username = "root";
String password = "123456";
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库 connection代表数据库
connection = DriverManager.getConnection(url, username, password);
//3.通知数据库开启事务 关闭自动提交 相当于开启事务
connection.setAutoCommit(false);
//4.编写SQL
String sql1 = "update account set money=money-100 where name='A'";
connection.prepareStatement(sql1).executeUpdate();
//制造错误
int i = 1 / 0;
String sql2 = "update account set money=money+100 where name='B'";
connection.prepareStatement(sql2).executeUpdate();
connection.commit();//以上两个SQL都执行成功了就提交时间
System.out.println("");
} catch (Exception e) {
connection.rollback();
e.printStackTrace();
} finally {
connection.close();
}
}
}
项目如何搭建
考虑用不用Maven 依赖 Jar
配置Tomcat
测试项目能否跑起来
导入项目中需要的jar包
<dependencies>
<dependency>
<groupId>javax.servletgroupId>
<artifactId>servlet-apiartifactId>
<version>2.5version>
dependency>
<dependency>
<groupId>javax.servlet.jspgroupId>
<artifactId>jsp-apiartifactId>
<version>2.1version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.31version>
dependency>
<dependency>
<groupId>jstlgroupId>
<artifactId>jstlartifactId>
<version>1.2version>
dependency>
<dependency>
<groupId>taglibsgroupId>
<artifactId>standardartifactId>
<version>1.1.2version>
dependency>
dependencies>
创建项目结构包
编写实体类
CREATE DATABASE `smbms`;
USE `smbms`;
DROP TABLE IF EXISTS `smbms_address`;
CREATE TABLE `smbms_address` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`contact` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系人姓名',
`addressDesc` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '收货地址明细',
`postCode` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '邮编',
`tel` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系人电话',
`createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者',
`creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
`modifyBy` BIGINT(20) DEFAULT NULL COMMENT '修改者',
`modifyDate` DATETIME DEFAULT NULL COMMENT '修改时间',
`userId` BIGINT(20) DEFAULT NULL COMMENT '用户ID',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `smbms_address`(`id`,`contact`,`addressDesc`,`postCode`,`tel`,`createdBy`,`creationDate`,`modifyBy`,`modifyDate`,`userId`) VALUES (1,'王丽','北京市东城区东交民巷44号','100010','13678789999',1,'2016-04-13 00:00:00',NULL,NULL,1),(2,'张红丽','北京市海淀区丹棱街3号','100000','18567672312',1,'2016-04-13 00:00:00',NULL,NULL,1),(3,'任志强','北京市东城区美术馆后街23号','100021','13387906742',1,'2016-04-13 00:00:00',NULL,NULL,1),(4,'曹颖','北京市朝阳区朝阳门南大街14号','100053','13568902323',1,'2016-04-13 00:00:00',NULL,NULL,2),(5,'李慧','北京市西城区三里河路南三巷3号','100032','18032356666',1,'2016-04-13 00:00:00',NULL,NULL,3),(6,'王国强','北京市顺义区高丽营镇金马工业区18号','100061','13787882222',1,'2016-04-13 00:00:00',NULL,NULL,3);
DROP TABLE IF EXISTS `smbms_bill`;
CREATE TABLE `smbms_bill` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`billCode` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '账单编码',
`productName` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '商品名称',
`productDesc` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '商品描述',
`productUnit` VARCHAR(10) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '商品单位',
`productCount` DECIMAL(20,2) DEFAULT NULL COMMENT '商品数量',
`totalPrice` DECIMAL(20,2) DEFAULT NULL COMMENT '商品总额',
`isPayment` INT(10) DEFAULT NULL COMMENT '是否支付(1:未支付 2:已支付)',
`createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者(userId)',
`creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
`modifyBy` BIGINT(20) DEFAULT NULL COMMENT '更新者(userId)',
`modifyDate` DATETIME DEFAULT NULL COMMENT '更新时间',
`providerId` BIGINT(20) DEFAULT NULL COMMENT '供应商ID',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=19 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `smbms_bill`(`id`,`billCode`,`productName`,`productDesc`,`productUnit`,`productCount`,`totalPrice`,`isPayment`,`createdBy`,`creationDate`,`modifyBy`,`modifyDate`,`providerId`) VALUES (2,'BILL2016_002','香皂、肥皂、药皂','日用品-皂类','块','1000.00','10000.00',2,1,'2016-03-23 04:20:40',NULL,NULL,13),(3,'BILL2016_003','大豆油','食品-食用油','斤','300.00','5890.00',2,1,'2014-12-14 13:02:03',NULL,NULL,6),(4,'BILL2016_004','橄榄油','食品-进口食用油','斤','200.00','9800.00',2,1,'2013-10-10 03:12:13',NULL,NULL,7),(5,'BILL2016_005','洗洁精','日用品-厨房清洁','瓶','500.00','7000.00',2,1,'2014-12-14 13:02:03',NULL,NULL,9),(6,'BILL2016_006','美国大杏仁','食品-坚果','袋','300.00','5000.00',2,1,'2016-04-14 06:08:09',NULL,NULL,4),(7,'BILL2016_007','沐浴液、精油','日用品-沐浴类','瓶','500.00','23000.00',1,1,'2016-07-22 10:10:22',NULL,NULL,14),(8,'BILL2016_008','不锈钢盘碗','日用品-厨房用具','个','600.00','6000.00',2,1,'2016-04-14 05:12:13',NULL,NULL,14),(9,'BILL2016_009','塑料杯','日用品-杯子','个','350.00','1750.00',2,1,'2016-02-04 11:40:20',NULL,NULL,14),(10,'BILL2016_010','豆瓣酱','食品-调料','瓶','200.00','2000.00',2,1,'2013-10-29 05:07:03',NULL,NULL,8),(11,'BILL2016_011','海之蓝','饮料-国酒','瓶','50.00','10000.00',1,1,'2016-04-14 16:16:00',NULL,NULL,1),(12,'BILL2016_012','芝华士','饮料-洋酒','瓶','20.00','6000.00',1,1,'2016-09-09 17:00:00',NULL,NULL,1),(13,'BILL2016_013','长城红葡萄酒','饮料-红酒','瓶','60.00','800.00',2,1,'2016-11-14 15:23:00',NULL,NULL,1),(14,'BILL2016_014','泰国香米','食品-大米','斤','400.00','5000.00',2,1,'2016-10-09 15:20:00',NULL,NULL,3),(15,'BILL2016_015','东北大米','食品-大米','斤','600.00','4000.00',2,1,'2016-11-14 14:00:00',NULL,NULL,3),(16,'BILL2016_016','可口可乐','饮料','瓶','2000.00','6000.00',2,1,'2012-03-27 13:03:01',NULL,NULL,2),(17,'BILL2016_017','脉动','饮料','瓶','1500.00','4500.00',2,1,'2016-05-10 12:00:00',NULL,NULL,2),(18,'BILL2016_018','哇哈哈','饮料','瓶','2000.00','4000.00',2,1,'2015-11-24 15:12:03',NULL,NULL,2);
DROP TABLE IF EXISTS `smbms_provider`;
CREATE TABLE `smbms_provider` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`proCode` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商编码',
`proName` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商名称',
`proDesc` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商详细描述',
`proContact` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '供应商联系人',
`proPhone` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '联系电话',
`proAddress` VARCHAR(50) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '地址',
`proFax` VARCHAR(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '传真',
`createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者(userId)',
`creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
`modifyDate` DATETIME DEFAULT NULL COMMENT '更新时间',
`modifyBy` BIGINT(20) DEFAULT NULL COMMENT '更新者(userId)',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `smbms_provider`(`id`,`proCode`,`proName`,`proDesc`,`proContact`,`proPhone`,`proAddress`,`proFax`,`createdBy`,`creationDate`,`modifyDate`,`modifyBy`) VALUES (1,'BJ_GYS001','北京三木堂商贸有限公司','长期合作伙伴,主营产品:茅台、五粮液、郎酒、酒鬼酒、泸州老窖、赖茅酒、法国红酒等','张国强','13566667777','北京市丰台区育芳园北路','010-58858787',1,'2013-03-21 16:52:07',NULL,NULL),(2,'HB_GYS001','石家庄帅益食品贸易有限公司','长期合作伙伴,主营产品:饮料、水饮料、植物蛋白饮料、休闲食品、果汁饮料、功能饮料等','王军','13309094212','河北省石家庄新华区','0311-67738876',1,'2016-04-13 04:20:40',NULL,NULL),(3,'GZ_GYS001','深圳市泰香米业有限公司','初次合作伙伴,主营产品:良记金轮米,龙轮香米等','郑程瀚','13402013312','广东省深圳市福田区深南大道6006华丰大厦','0755-67776212',1,'2014-03-21 16:56:07',NULL,NULL),(4,'GZ_GYS002','深圳市喜来客商贸有限公司','长期合作伙伴,主营产品:坚果炒货.果脯蜜饯.天然花茶.营养豆豆.特色美食.进口食品.海味零食.肉脯肉','林妮','18599897645','广东省深圳市福龙工业区B2栋3楼西','0755-67772341',1,'2013-03-22 16:52:07',NULL,NULL),(5,'JS_GYS001','兴化佳美调味品厂','长期合作伙伴,主营产品:天然香辛料、鸡精、复合调味料','徐国洋','13754444221','江苏省兴化市林湖工业区','0523-21299098',1,'2015-11-22 16:52:07',NULL,NULL),(6,'BJ_GYS002','北京纳福尔食用油有限公司','长期合作伙伴,主营产品:山茶油、大豆油、花生油、橄榄油等','马莺','13422235678','北京市朝阳区珠江帝景1号楼','010-588634233',1,'2012-03-21 17:52:07',NULL,NULL),(7,'BJ_GYS003','北京国粮食用油有限公司','初次合作伙伴,主营产品:花生油、大豆油、小磨油等','王驰','13344441135','北京大兴青云店开发区','010-588134111',1,'2016-04-13 00:00:00',NULL,NULL),(8,'ZJ_GYS001','慈溪市广和绿色食品厂','长期合作伙伴,主营产品:豆瓣酱、黄豆酱、甜面酱,辣椒,大蒜等农产品','薛圣丹','18099953223','浙江省宁波市慈溪周巷小安村','0574-34449090',1,'2013-11-21 06:02:07',NULL,NULL),(9,'GX_GYS001','优百商贸有限公司','长期合作伙伴,主营产品:日化产品','李立国','13323566543','广西南宁市秀厢大道42-1号','0771-98861134',1,'2013-03-21 19:52:07',NULL,NULL),(10,'JS_GYS002','南京火头军信息技术有限公司','长期合作伙伴,主营产品:不锈钢厨具等','陈女士','13098992113','江苏省南京市浦口区浦口大道1号新城总部大厦A座903室','025-86223345',1,'2013-03-25 16:52:07',NULL,NULL),(11,'GZ_GYS003','广州市白云区美星五金制品厂','长期合作伙伴,主营产品:海绵床垫、坐垫、靠垫、海绵枕头、头枕等','梁天','13562276775','广州市白云区钟落潭镇福龙路20号','020-85542231',1,'2016-12-21 06:12:17',NULL,NULL),(12,'BJ_GYS004','北京隆盛日化科技','长期合作伙伴,主营产品:日化环保清洗剂,家居洗涤专卖、洗涤用品网、墙体除霉剂、墙面霉菌清除剂等','孙欣','13689865678','北京市大兴区旧宫','010-35576786',1,'2014-11-21 12:51:11',NULL,NULL),(13,'SD_GYS001','山东豪克华光联合发展有限公司','长期合作伙伴,主营产品:洗衣皂、洗衣粉、洗衣液、洗洁精、消杀类、香皂等','吴洪转','13245468787','山东济阳济北工业区仁和街21号','0531-53362445',1,'2015-01-28 10:52:07',NULL,NULL),(14,'JS_GYS003','无锡喜源坤商行','长期合作伙伴,主营产品:日化品批销','周一清','18567674532','江苏无锡盛岸西路','0510-32274422',1,'2016-04-23 11:11:11',NULL,NULL),(15,'ZJ_GYS002','乐摆日用品厂','长期合作伙伴,主营产品:各种中、高档塑料杯,塑料乐扣水杯(密封杯)、保鲜杯(保鲜盒)、广告杯、礼品杯','王世杰','13212331567','浙江省金华市义乌市义东路','0579-34452321',1,'2016-08-22 10:01:30',NULL,NULL);
DROP TABLE IF EXISTS `smbms_role`;
CREATE TABLE `smbms_role` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`roleCode` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '角色编码',
`roleName` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '角色名称',
`createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者',
`creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
`modifyBy` BIGINT(20) DEFAULT NULL COMMENT '修改者',
`modifyDate` DATETIME DEFAULT NULL COMMENT '修改时间',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `smbms_role`(`id`,`roleCode`,`roleName`,`createdBy`,`creationDate`,`modifyBy`,`modifyDate`) VALUES (1,'SMBMS_ADMIN','系统管理员',1,'2016-04-13 00:00:00',NULL,NULL),(2,'SMBMS_MANAGER','经理',1,'2016-04-13 00:00:00',NULL,NULL),(3,'SMBMS_EMPLOYEE','普通员工',1,'2016-04-13 00:00:00',NULL,NULL);
DROP TABLE IF EXISTS `smbms_user`;
CREATE TABLE `smbms_user` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`userCode` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户编码',
`userName` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户名称',
`userPassword` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '用户密码',
`gender` INT(10) DEFAULT NULL COMMENT '性别(1:女、 2:男)',
`birthday` DATE DEFAULT NULL COMMENT '出生日期',
`phone` VARCHAR(15) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '手机',
`address` VARCHAR(30) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT '地址',
`userRole` BIGINT(20) DEFAULT NULL COMMENT '用户角色(取自角色表-角色id)',
`createdBy` BIGINT(20) DEFAULT NULL COMMENT '创建者(userId)',
`creationDate` DATETIME DEFAULT NULL COMMENT '创建时间',
`modifyBy` BIGINT(20) DEFAULT NULL COMMENT '更新者(userId)',
`modifyDate` DATETIME DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
INSERT INTO `smbms_user`(`id`,`userCode`,`userName`,`userPassword`,`gender`,`birthday`,`phone`,`address`,`userRole`,`createdBy`,`creationDate`,`modifyBy`,`modifyDate`) VALUES (1,'admin','系统管理员','1234567',1,'1983-10-10','13688889999','北京市海淀区成府路207号',1,1,'2013-03-21 16:52:07',NULL,NULL),(2,'liming','李明','0000000',2,'1983-12-10','13688884457','北京市东城区前门东大街9号',2,1,'2014-12-31 19:52:09',NULL,NULL),(5,'hanlubiao','韩路彪','0000000',2,'1984-06-05','18567542321','北京市朝阳区北辰中心12号',2,1,'2014-12-31 19:52:09',NULL,NULL),(6,'zhanghua','张华','0000000',1,'1983-06-15','13544561111','北京市海淀区学院路61号',3,1,'2013-02-11 10:51:17',NULL,NULL),(7,'wangyang','王洋','0000000',2,'1982-12-31','13444561124','北京市海淀区西二旗辉煌国际16层',3,1,'2014-06-11 19:09:07',NULL,NULL),(8,'zhaoyan','赵燕','0000000',1,'1986-03-07','18098764545','北京市海淀区回龙观小区10号楼',3,1,'2016-04-21 13:54:07',NULL,NULL),(10,'sunlei','孙磊','0000000',2,'1981-01-04','13387676765','北京市朝阳区管庄新月小区12楼',3,1,'2015-05-06 10:52:07',NULL,NULL),(11,'sunxing','孙兴','0000000',2,'1978-03-12','13367890900','北京市朝阳区建国门南大街10号',3,1,'2016-11-09 16:51:17',NULL,NULL),(12,'zhangchen','张晨','0000000',1,'1986-03-28','18098765434','朝阳区管庄路口北柏林爱乐三期13号楼',3,1,'2016-08-09 05:52:37',1,'2016-04-14 14:15:36'),(13,'dengchao','邓超','0000000',2,'1981-11-04','13689674534','北京市海淀区北航家属院10号楼',3,1,'2016-07-11 08:02:47',NULL,NULL),(14,'yangguo','杨过','0000000',2,'1980-01-01','13388886623','北京市朝阳区北苑家园茉莉园20号楼',3,1,'2015-02-01 03:52:07',NULL,NULL),(15,'zhaomin','赵敏','0000000',1,'1987-12-04','18099897657','北京市昌平区天通苑3区12号楼',2,1,'2015-09-12 12:02:12',NULL,NULL);
ORM映射 表-类映射
import java.util.Date;
public class User {
private Integer id; //id
private String userCode; //用户编码
private String userName; //用户名称
private String userPassword; //用户密码
private Integer gender; //性别
private Date birthday; //出生日期
private String phone; //电话
private String address; //地址
private Integer userRole; //用户角色
private Integer createdBy; //创建者
private Date creationDate; //创建时间
private Integer modifyBy; //更新者
private Date modifyDate; //更新时间
private Integer age;//年龄
private String userRoleName; //用户角色名称
public String getUserRoleName() {
return userRoleName;
}
public void setUserRoleName(String userRoleName) {
this.userRoleName = userRoleName;
}
public Integer getAge() {
Date date = new Date();
Integer age = date.getYear()-birthday.getYear();
return age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserCode() {
return userCode;
}
public void setUserCode(String userCode) {
this.userCode = userCode;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public Integer getGender() {
return gender;
}
public void setGender(Integer gender) {
this.gender = gender;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getUserRole() {
return userRole;
}
public void setUserRole(Integer userRole) {
this.userRole = userRole;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
import java.math.BigDecimal;
import java.util.Date;
public class Bill {
private Integer id; //id
private String billCode; //账单编码
private String productName; //商品名称
private String productDesc; //商品描述
private String productUnit; //商品单位
private BigDecimal productCount; //商品数量
private BigDecimal totalPrice; //总金额
private Integer isPayment; //是否支付
private Integer providerId; //供应商ID
private Integer createdBy; //创建者
private Date creationDate; //创建时间
private Integer modifyBy; //更新者
private Date modifyDate;//更新时间
private String providerName;//供应商名称
public String getProviderName() {
return providerName;
}
public void setProviderName(String providerName) {
this.providerName = providerName;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBillCode() {
return billCode;
}
public void setBillCode(String billCode) {
this.billCode = billCode;
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getProductDesc() {
return productDesc;
}
public void setProductDesc(String productDesc) {
this.productDesc = productDesc;
}
public String getProductUnit() {
return productUnit;
}
public void setProductUnit(String productUnit) {
this.productUnit = productUnit;
}
public BigDecimal getProductCount() {
return productCount;
}
public void setProductCount(BigDecimal productCount) {
this.productCount = productCount;
}
public BigDecimal getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(BigDecimal totalPrice) {
this.totalPrice = totalPrice;
}
public Integer getIsPayment() {
return isPayment;
}
public void setIsPayment(Integer isPayment) {
this.isPayment = isPayment;
}
public Integer getProviderId() {
return providerId;
}
public void setProviderId(Integer providerId) {
this.providerId = providerId;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
import java.util.Date;
public class Role {
private Integer id; //id
private String roleCode; //角色编码
private String roleName; //角色名称
private Integer createdBy; //创建者
private Date creationDate; //创建时间
private Integer modifyBy; //更新者
private Date modifyDate;//更新时间
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getRoleCode() {
return roleCode;
}
public void setRoleCode(String roleCode) {
this.roleCode = roleCode;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
import java.util.Date;
public class Provider {
private Integer id; //id
private String proCode; //供应商编码
private String proName; //供应商名称
private String proDesc; //供应商描述
private String proContact; //供应商联系人
private String proPhone; //供应商电话
private String proAddress; //供应商地址
private String proFax; //供应商传真
private Integer createdBy; //创建者
private Date creationDate; //创建时间
private Integer modifyBy; //更新者
private Date modifyDate;//更新时间
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getProCode() {
return proCode;
}
public void setProCode(String proCode) {
this.proCode = proCode;
}
public String getProName() {
return proName;
}
public void setProName(String proName) {
this.proName = proName;
}
public String getProDesc() {
return proDesc;
}
public void setProDesc(String proDesc) {
this.proDesc = proDesc;
}
public String getProContact() {
return proContact;
}
public void setProContact(String proContact) {
this.proContact = proContact;
}
public String getProPhone() {
return proPhone;
}
public void setProPhone(String proPhone) {
this.proPhone = proPhone;
}
public String getProAddress() {
return proAddress;
}
public void setProAddress(String proAddress) {
this.proAddress = proAddress;
}
public String getProFax() {
return proFax;
}
public void setProFax(String proFax) {
this.proFax = proFax;
}
public Integer getCreatedBy() {
return createdBy;
}
public void setCreatedBy(Integer createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public Integer getModifyBy() {
return modifyBy;
}
public void setModifyBy(Integer modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8
username=root
password=123456
package com.lhc.dao;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class BaseDao {
private static String driver;
private static String url;
private static String username;
private static String password;
//静态代码块
static {
//通过类加载器 读取对应的资源
InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
Properties properties = new Properties();
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
}
//获取数据库的连接
public static Connection getConnection() {
Connection connection = null;
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, username, password);
System.out.println("连接成功");
} catch (Exception e) {
System.out.println("连接失败");
e.printStackTrace();
}
return connection;
}
//编写查询公共类
public static ResultSet execute(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet, String sql, Object[] params) throws SQLException {
//预编译的sql 在后面直接执行就可以了
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
//因为 preparedStatement.setObject是从 1 开始的
preparedStatement.setObject(i + 1, params[i]);
}
resultSet = preparedStatement.executeQuery();
return resultSet;
}
//编写增删改公共类
public static int execute(Connection connection, PreparedStatement preparedStatement, String sql, Object[] params) throws SQLException {
preparedStatement = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
//因为 preparedStatement.setObject是从 1 开始的
preparedStatement.setObject(i + 1, params[i]);
}
int i = preparedStatement.executeUpdate();
return i;
}
//释放资源
public static boolean closeResource(Connection connection, PreparedStatement preparedStatement, ResultSet resultSet) {
boolean flag = true;
if (resultSet != null) {
try {
resultSet.close();
//GC回收
resultSet = null;
} catch (SQLException throwables) {
throwables.printStackTrace();
flag = false;
}
}
if (preparedStatement != null) {
try {
preparedStatement.close();
//GC回收
preparedStatement = null;
} catch (SQLException throwables) {
throwables.printStackTrace();
flag = false;
}
}
if (connection != null) {
try {
connection.close();
//GC回收
resultSet = null;
} catch (SQLException throwables) {
throwables.printStackTrace();
flag = false;
}
}
return flag;
}
}
<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"
metadata-complete="true">
<filter>
<filter-name>CharacterEncodingFilterfilter-name>
<filter-class>com.lhc.filter.CharacterEncodingFilterfilter-class>
filter>
<filter-mapping>
<filter-name>CharacterEncodingFilterfilter-name>
<url-pattern>/*url-pattern>
filter-mapping>
web-app>
码云服务器里有
https://gitee.com/babobenNB/smbms?_from=gitee_search
编写前端页面
设置首页
web.xml
<welcome-file-list>
<welcome-file>login.jspwelcome-file>
welcome-file-list>
编写 dao层用户登入的窗口
package com.lhc.dao.user;
import com.lhc.pojo.User;
import java.sql.Connection;
import java.sql.SQLException;
public interface UserDao {
//得到要登入的用户
public User getLoginUser(Connection connection,String userCode) throws SQLException;
}
编写dao接口的实现类
package com.lhc.dao.user;
import com.lhc.dao.BaseDao;
import com.lhc.pojo.User;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDaoImpl implements UserDao {
public User getLoginUser(Connection connection, String userCode) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
User user = null;
if (connection != null) {
String sql = "select * from smbms_user where userCode=?";
Object[] params = {userCode};
BaseDao.executeQuery(connection, pstm, rs, sql, params);
if (rs.next()) {
user = new User();
user = new User();
user.setId(rs.getInt("id"));
user.setUserCode(rs.getString("userCode"));
user.setUserName(rs.getString("userName"));
user.setUserPassword(rs.getString("userPassword"));
user.setGender(rs.getInt("gender"));
user.setBirthday(rs.getDate("birthday"));
user.setPhone(rs.getString("phone"));
user.setAddress(rs.getString("address"));
user.setUserRole(rs.getInt("userRole"));
user.setCreatedBy(rs.getInt("createdBy"));
user.setCreationDate(rs.getTimestamp("creationDate"));
user.setModifyBy(rs.getInt("modifyBy"));
user.setModifyDate(rs.getTimestamp("modifyDate"));
}
BaseDao.closeResource(null, pstm, rs);
}
return user;
}
}
业务层接口
package com.lhc.service;
import com.lhc.pojo.User;
public interface UserService {
//用户登入
public User login(String userCode,String password);
}
业务层实现类
package com.lhc.service;
import com.lhc.dao.BaseDao;
import com.lhc.dao.user.UserDao;
import com.lhc.dao.user.UserDaoImpl;
import com.lhc.pojo.User;
import org.junit.Test;
import java.sql.Connection;
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserServiceImpl(){
userDao= new UserDaoImpl();
}
public User login(String userCode, String password) {
//业务层都会调用Dao层 所以我们要引入Dao层
Connection connection=null;
User user=null;
try {
connection= BaseDao.getConnection();
System.out.println("连接成功");
//通过业务层调用对应的具体的数据库操作
user = userDao.getLoginUser(connection, userCode, password);
} catch (Exception e) {
e.printStackTrace();
} finally {
BaseDao.closeResource(connection,null,null);
}
return user;
}
}
编写servlet
package com.lhc.servlet.user;
import com.lhc.pojo.User;
import com.lhc.service.UserService;
import com.lhc.service.UserServiceImpl;
import com.lhc.util.Constant;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class LoginServlet extends HttpServlet {
//servlet 控制层 调用业务层代码
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入LoginServlet---start...");
//获取用户名和密码
String userCode = req.getParameter("userCode");
String userpassword = req.getParameter("userpassword");
//和数据库中的密码进行对比 调用业务层
UserServiceImpl userService = new UserServiceImpl();
User user = userService.login(userCode, userpassword);//这里已经把登入的人给查出来了
if (user!=null){//查有此人 可以登入
//将用户的信息 放到Session中
req.getSession().setAttribute(Constant.USER_SESSION,user);
//跳转到主页
resp.sendRedirect("jsp/frame.jsp");
}else {//查无此人
req.setAttribute("error","用户或者密码错误");
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
注册Servlet
<servlet>
<servlet-name>LoginServletservlet-name>
<servlet-class>com.lhc.servlet.user.LoginServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>LoginServletservlet-name>
<url-pattern>/login.dourl-pattern>
servlet-mapping>
测试访问 确保以上功能成功!
注销功能
思路 移除session 返回登入页面
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//移除用户的Constant.USER_SESSION
req.getSession().removeAttribute(Constant.USER_SESSION);
resp.sendRedirect(req.getContextPath()+"/login.jsp");//返回登入页面 req.getContextPath()是到webapp路径下
}
xml注册
<servlet>
<servlet-name>LogoutServletservlet-name>
<servlet-class>com.lhc.servlet.user.LogoutServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>LogoutServletservlet-name>
<url-pattern>/jsp/logout.dourl-pattern>
servlet-mapping>
查看session是否存在
过滤器
public void doFilter(ServletRequest req ,ServletResponse resp, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//过滤器 从session中获取用户
User user = (User) request.getSession().getAttribute(Constant.USER_SESSION);
if (user==null){//已经被移除或者注销了 或者未登入
response.sendRedirect("smbms/error.jsp");
}else {
chain.doFilter(req,resp);
}
}
web.xml
<filter>
<filter-name>SysFilterfilter-name>
<filter-class>com.lhc.filter.SysFilterfilter-class>
filter>
<filter-mapping>
<filter-name>SysFilterfilter-name>
<url-pattern>/jsp/*url-pattern>
filter-mapping>
登入 注销 拦截 完成
导入前端页面
写项目 从底层向上写
UserDao接口
public int updatePwd(Connection connection,int id,String password) throws SQLException;
UserDao接口实现类
public int updatePwd(Connection connection, int id, String password) throws SQLException {
PreparedStatement pstm = null;
int execute = 0;
if (connection != null) {
String sql = "update smbms_user set userPassword=? where id=?";
Object params[] = {password, id};
execute = BaseDao.execute(connection, pstm, sql, params);
BaseDao.closeResource(null, pstm, null);
}
return execute;
}
Userservice接口
//根据user ID 修改密码
public boolean updatePwd(int id, String password) throws SQLException;
UserService实现类
public boolean updatePwd(int id, String password) throws SQLException {
Connection connection = null;
boolean flag = false;
connection = BaseDao.getConnection();
try {
//修改密码
if (userDao.updatePwd(connection, id, password) > 0) {
flag = true;
}
} catch (Exception e) {
e.printStackTrace();
BaseDao.closeResource(connection, null, null);
}
return flag;
}
Servlet层
//修改密码
public void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//从Session里拿ID
Object o = req.getSession().getAttribute(Constant.USER_SESSION);
boolean flag = false;
String newpassword = req.getParameter("newpassword");
if (o != null && !StringUtils.isEmptyOrWhitespaceOnly(newpassword)) {
try {
UserServiceImpl userService = new UserServiceImpl();
flag = userService.updatePwd(((User) o).getId(), newpassword);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
if (flag) {
req.setAttribute("message", "修改密码成功,请退出 使用新密码登入");
//密码修改成功 移除当前session
req.getSession().removeAttribute(Constant.USER_SESSION);
} else {
//密码修改失败
req.setAttribute("message", "修改密码失败");
}
} else {
//密码修改失败
req.setAttribute("message", "修改密码有问题");
}
req.getRequestDispatcher("pwdmodify.jsp").forward(req, resp);
}
记得实现服用 需要提取出方法
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if (method.equals("savepwd")&&method!=null){
this.update(req,resp);
}
}
测试成功
阿里巴巴的fastjson
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>1.2.61version>
dependency>
后台代码
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if (method.equals("savepwd") && method != null) {
try {
this.update(req, resp);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}else if (method.equals("pwdmodify")&&method != null){
Object o = req.getSession().getAttribute(Constant.USER_SESSION);
String oldpassword = req.getParameter("oldpassword");
//万能的Map 结果集
HashMap<String, String> resultMap = new HashMap<String,String>();
if (o==null){
//session失效了 或者过期
resultMap.put("result","sessionerror");
}else if (StringUtils.isEmptyOrWhitespaceOnly(oldpassword)){
resultMap.put("result","error");
}else {
String userPassword = ((User) o).getUserPassword();//session中用户的密码
if (oldpassword.equals(userPassword)){
resultMap.put("result","true");
}else {
resultMap.put("result","false");
}
}
//返回一个json文件
resp.setContentType("application/json");;
PrintWriter writer = resp.getWriter();
//JSONArray 阿里巴巴的json工具类 转换格式
/*
resultMap.put("result","sessionerror")
转换成json的格式{key:value}
*/
writer.write(JSONArray.toJSONString(resultMap));
writer.flush();
writer.close();
}
}
思路
导入分页的工具类
用户列表页面导入
userlist.jsp
public int getUserCount(String username,int userRole) throws SQLException;
//根据用户名或者角色查询用户总数
public int getUserCount(String username, int userRole) throws SQLException {
PreparedStatement pstm = null;
ResultSet rs = null;
Integer count = 0;
Connection connection = BaseDao.getConnection();
if (connection != null) {
StringBuffer sql = new StringBuffer();
sql.append("select count(1) as count from smbms_user u,smbms_role r where u.userRole=r.id");
ArrayList<Object> list = new ArrayList<Object>();//存放我们的数据
if (!StringUtils.isNullOrEmpty(username)) {
sql.append("and u.username like ?");
list.add("%" + username + "%");//index:0
}
if (userRole > 0) {
sql.append(" and u.userRole =?");
list.add(userRole);//index:1
}
//怎么List转换为数组
Object[] params = list.toArray();
System.out.println("UserDaoImpl-->getUserCount:" + sql.toString());
rs = BaseDao.execute(connection, pstm, rs, sql.toString(), params);
if (rs.next()) {
count = rs.getInt("count");//从结果集中获得数量
}
BaseDao.closeResource(connection, pstm, rs);
}
return count;
}
//查询记录数
public int getUserCount(String username,int userRole);
public int getUserCount(String username, int userRole) {
int count=0;
Connection connection = null;
try {
connection = BaseDao.getConnection();
count = userDao.getUserCount(username, userRole);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return count;
}
5.Servlet
//获取用户列表
public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize)throws Exception;
public List<User> getUserList(Connection connection,String userName, int userRole, int currentPageNo, int pageSize) throws Exception {
// TODO Auto-generated method stub
PreparedStatement pstm = null;
ResultSet rs = null;
List<User> userList = new ArrayList<User>();
if(connection != null){
StringBuffer sql = new StringBuffer();
sql.append("select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.userRole = r.id");
List<Object> list = new ArrayList<Object>();
if(!StringUtils.isNullOrEmpty(userName)){
sql.append(" and u.userName like ?");
list.add("%"+userName+"%");
}
if(userRole > 0){
sql.append(" and u.userRole = ?");
list.add(userRole);
}
//在数据库中 分页使用 limit startIndex,pageSize 总数
//当前页 (当前页-1)*页面大小
// 0,5 1 0 01234
//6,5 2 6 56789
//11,5 3 10
sql.append(" order by creationDate DESC limit ?,?");
currentPageNo = (currentPageNo-1)*pageSize;
list.add(currentPageNo);
list.add(pageSize);
Object[] params = list.toArray();
System.out.println("sql ----> " + sql.toString());
rs = BaseDao.execute(connection,pstm, rs, sql.toString(), params);
while(rs.next()){
User _user = new User();
_user.setId(rs.getInt("id"));
_user.setUserCode(rs.getString("userCode"));
_user.setUserName(rs.getString("userName"));
_user.setGender(rs.getInt("gender"));
_user.setBirthday(rs.getDate("birthday"));
_user.setPhone(rs.getString("phone"));
_user.setUserRole(rs.getInt("userRole"));
_user.setUserRoleName(rs.getString("userRoleName"));
userList.add(_user);
}
BaseDao.closeResource(null, pstm, rs);
}
return userList;
}
//通过条件查询 -userList
public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize);
public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) {
// TODO Auto-generated method stub
Connection connection = null;
List<User> userList = null;
System.out.println("queryUserName ---- > " + queryUserName);
System.out.println("queryUserRole ---- > " + queryUserRole);
System.out.println("currentPageNo ---- > " + currentPageNo);
System.out.println("pageSize ---- > " + pageSize);
try {
connection = BaseDao.getConnection();
userList = userDao.getUserList(connection, queryUserName,queryUserRole,currentPageNo,pageSize);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
BaseDao.closeResource(connection, null, null);
}
return userList;
}
为了我们职责同一 可以把角色的操作单独放在一个包中 和POJO类对应
//获取角色列表
public List<Role> getRoleList(Connection connection)throws SQLException;
//获取角色列表
public List<Role> getRoleList(Connection connection) throws SQLException {
PreparedStatement pstm=null;
ResultSet rs=null;
ArrayList<Role> roleList = new ArrayList<Role>();
if (connection!=null){
String sql="select * from smbms_role";
Object[] params={};
rs=BaseDao.execute(connection,pstm,rs,sql,params);
while (rs.next()){
Role role = new Role();
role.setId(rs.getInt("id"));
role.setRoleCode(rs.getString("rolename"));
role.setRoleName(rs.getString("roleCode"));
roleList.add(role);
}
BaseDao.closeResource(connection,pstm,rs);
}
return roleList;
}
public List<Role> getRoleList();
//引入Dao
private RoleDao roleDao;
public RoleServiceImpl() {
roleDao= new RoleDaoImpl();
}
public List<Role> getRoleList() {
Connection connection = null;
List<Role> roleList=null;
try {
connection=BaseDao.getConnection();
roleList= roleDao.getRoleList(connection);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
BaseDao.closeResource(connection,null,null);
}
return roleList;
}
//query方法
public void query(HttpServletRequest req, HttpServletResponse resp){
//查询用户列表
//从前端获取数据;
String queryUserName = req.getParameter("queryname");
String temp = req.getParameter("queryUserRole");
String pageIndex = req.getParameter("pageIndex");
int queryUserRole = 0;
//获取用户列表
UserServiceImpl userService = new UserServiceImpl();
List<User> userList = null;
//第一次走这个请求,一定是第一页,页面大小固定的;
int pageSize = 5; //可以把这个些到配置文件中,方便后期修改;
int currentPageNo = 1;
if (queryUserName ==null){
queryUserName = "";
}
if (temp!=null && !temp.equals("")){
queryUserRole = Integer.parseInt(temp); //给查询赋值!0,1,2,3
}
if (pageIndex!=null){
currentPageNo = Integer.parseInt(pageIndex);
}
//获取用户的总数 (分页: 上一页,下一页的情况)
int totalCount = userService.getUserCount(queryUserName, queryUserRole);
//总页数支持
PageSupport pageSupport = new PageSupport();
pageSupport.setCurrentPageNo(currentPageNo);
pageSupport.setPageSize(pageSize);
pageSupport.setTotalCount(totalCount);
int totalPageCount = ((int)(totalCount/pageSize))+1;
//控制首页和尾页
//如果页面要小于1了,就显示第一页的东西
if (currentPageNo<1){
currentPageNo = 1;
}else if (currentPageNo>totalPageCount){ //当前页面大于了最后一页;
currentPageNo = totalPageCount;
}
//获取用户列表展示
userList = userService.getUserList(queryUserName, queryUserRole, currentPageNo, pageSize);
req.setAttribute("userList",userList);
RoleServiceImpl roleService = new RoleServiceImpl();//用户名需要给下拉框里传值 因为前端用jstl表达式帮我们拆解这个List 所以我们传入List类型就行
List<Role> roleList = roleService.getRoleList();
req.setAttribute("roleList",roleList);
req.setAttribute("totalCount",totalCount);
req.setAttribute("currentPageNo",currentPageNo);
req.setAttribute("totalPageCount",totalPageCount);
req.setAttribute("queryUserName",queryUserName);
req.setAttribute("queryUserRole",queryUserRole);
//返回前端
try {
req.getRequestDispatcher("userlist.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}