SERVLET从入门到精通(一)

SERVLET
目录(单击跳转对应目录)
1.SERVLET架构............................................................. 2
1.1十三种技术J2EE的................................................... 2
1.2入门JAVAWEB........................................................ 2
1.3详解tomcat......................................................... 3
1.4WEB程序目录结构..................................................... 4
1.5Tomcat的虚拟目录.................................................... 5
1.6Tomcat体系再说明.................................................... 5
2.SERVLET的必要性......................................................... 6
2.1需求................................................................ 6
2.2SERVLET的快速入门案例............................................... 6
2.3SERVLET生命周期..................................................... 8
2.4使用继承HttpServlet的方法来开发servlet............................ 8
2.5使用Eclipse+Maven开发servlet/jsp/spring.......................... 11
3.Servlet细节............................................................ 11
3.1配置文件详解....................................................... 11
3.2servlet类是由java引擎(WEB服务器)调用的java类/无法独立运行的... 13
3.3网站启动时需要创建临时表........................................... 15
3.4ServletConfig对象/用于读取servlet的配置信息....................... 18
4.实际网站开发............................................................ 19
4.1用户登录1.0版..................................................... 19
4.2深度剖析HTTP协议.................................................. 24
4.3HTTP响应........................................................... 26
4.4Servlet的三大改进.................................................. 29
4.5技术深入优化....................................................... 48
5.会话技术................................................................ 93
5.1Cookie技术......................................................... 93
5.2session........................................................... 103
6.网站计数器............................................................. 120
6.1ServletContext的使用.............................................. 120
6.3网站计数器........................................................ 126
6.4关于SqlHelper工具类几点问题说明.................................. 132
1.JSP第一讲............................................................. 132
1.1十三种技术介绍.................................................... 132
1.2卖油翁的故事...................................................... 133
1.3用户管理系统JSP版................................................ 133
1.4JSP概述/基本语法.................................................. 133
1.5JSP运行原理....................................................... 133
1.6计算器JSP版...................................................... 136
2.简单的用户登录系统【纯JSP版】......................................... 144
2.1第一版初级版...................................................... 144
2.2用户登录系统分页有很大的优化空间.................................. 147
2.3session技术....................................................... 170
2.4用户管理系统增删改查的改进........................................ 173
3.网上购物商城(我用springmvc来做)..................................... 178
3.1需求分析.......................................................... 178
3.2系统框架分析...................................................... 179
3.3网站设计.......................................................... 179
3.4购物网站界面设计.................................................. 179
3.5数据库设计........................................................ 180
3.6网站设计代码...................................................... 180
3.7springmvc开发新的总结............................................. 1991.SERVLET架构
1.1十三种技术J2EE的
1.1.1核心技术
1.1.1.1JAVA/SERVLET/JSP这是基础
1.1.1.2还有JDBC/命名规范/JAVAMAIL/JAVABEANS/JMS/XML/框架部分
SPRING/SPRINGMVC/MYBATIS/MAVEN
1.1.1.3个人学习现有的技术
A.基础和进阶(对象/集合/界面/线程/网络/文件)
B.数据库JDBC/MySql/Oracle/SqlServer
C.网页设计HTML/CSS/JS
D.配置XML
1.1.1.4即将需要讲的技术SERVLET
1.1.1.5将来还有各种高级框架Ajax/Extjs/Jquery/Spring/AndSoOn1.2入门JAVAWEB
1.2.1动态网页技术发展历程
1.2.1.1动静态网页
A.静态页面
B.动态页面 用户可以输入数据和页面交互(注册购物发帖)/不同时间打开页面内容是变化的
C.动态页面开发技术SERVLET/JSP
1.2.1.2简单历程CGI—ASP—PHP—JSP(跨平台型/可伸缩性/一次编写到处运行)
1.2.2比较BS和CS
1.2.2.1讲解BS
A.浏览器Browser/服务器Server(代码/需要网络/请求—回复/)
B.主页index.jsp 发出HTTP请求—返回HTML页面给浏览器(然后来展示给用户)
1.2.2.2讲解CS
A.客户端Client(程序员开发的QQ/MSN/)/服务器Server(代码/需要网络/请求—回复/)
B.用的是TCP/IP协议/Socket编程 服务端返回结果
1.2.2.3比较优缺点
A.模式BS开发成本低/管理维护和产品升级便利/对用户的培训费用低/出现故障的概率小
B.模式BS不足安全性不足/客户端收到浏览器的限制1.3详解tomcat
1.3.1自己模拟开发WEB服务器
1.3.1.1自己服务器JAVA代码示例
package surface;
import java.io.IOException;
import java.io.*;
import java.net.*;
public class MyWebServer {
public static void main(String args[]) throws Exception{
ServerSocket serverSocket=new ServerSocket(80);//也可以用别的端口
while(true){
Socket MySocket=serverSocket.accept();
//提示一句话
System.err.println("在80端口等待连接....");
OutputStream outputStream=MySocket.getOutputStream();
BufferedReader bufferedReader=new BufferedReader(new FileReader("F:/index.jsp"));
String buffer="";
while((buffer=bufferedReader.readLine())!=null){
outputStream.write(buffer.getBytes());
}
//关闭流
bufferedReader.close();
outputStream.close();
MySocket.close();
}
}
}
1.3.2一款阿帕奇开源组织下的一个产品
1.3.2.1支持windows和linux系统
1.3.2.2解压即安装
1.3.2.3运行报错解决
A.编辑startup最后加上pause
B.需要JAVA_HOME对应C:Program FilesJavajdk1.8.0_161安装目录(单独不要带分号)
C.启动成功后浏览器输入http://localhost:8080/访问即可
D.已经占用过的端口,无法二次启用 —/关闭对应端口再启用 netstat -ano—进程管理里杀掉就行
E.使用别的端口 —tomcat中conf中server.xml中修改端口(可以为80)
F.能正常启动/但是总是定向不对 IE加载下修改下搜索提供程序
G.如果不配置环境变量也可以在startup加 set JAVA_HOME=C:Program FilesJavajdk1.8.0_161
1.3.3tomcat的目录层次结构
1.3.3.1目录BIN 启动/关闭tomcat的bat文件
1.3.3.2配置conf
A.server.xml该文件配置server相关的信息,如启动端口号/配置Host/配置context即web应用
B.web.xml该文件配置与web应用(相当于一个web站点)
C.tomcat-users.xml该文件用于配置tomcat的管理用户名和密码
1.3.3.3目录lib放置tomcat运行需要的JAR包
1.3.3.4目录logs存放日志的地方
1.3.3.5目录webapps存放我们的web站点文件
A.如建立了MyWeb文件夹,里面放个Hello的html/6.0以后才支持的
B.访问原理 协议+主机+端口+/web应用/资源文件(URI) /整体叫做URL
C.访问WEB应用的某个文件http://localhost/MyWeb/Hello.html
1.3.3.6目录work该目录用于存放JSP被访问后生成的对应的那个servlet文件以及class文件1.4WEB程序目录结构
1.4.1有多个资源组成
1.4.1.1可以包含Html/CSS/JS/JAVA程序/动态页面/视频
1.4.1.2要求设置成主页/则需要把WEB应用的目录格式做的更加规范/
1.4.1.3在web.xml添加<welcome-file-list><welcome-file>主页.html/jsp</welcome-file></welcome-file-list>1.5Tomcat的虚拟目录
1.5.1如何管理其他目录下的web应用
1.5.1.1虚拟目录配置
A.在tomcat的conf目录下的server.xml的<Host>节点间添加如下代码
<Context path="/Hi" docBase="F:Hi"/>/而且不影响原目录的访问
B.修改完毕肯定要重新启动汤姆猫才可以的
1.5.2设置域名和端口修改成80
1.5.2.1如何配置自己的主机名wdfgdzx.com实现步骤
A.浏览器访问一个网站的流程图
浏览器localhost—解析主机名即:localhost—查询本机的hosts文件—查到(就直接访问查询到的IP地址)/查不到—查DNS服务
—查到(就直接访问查询到的IP地址)/查不到(直接返回错误)
查到详细:尝试连接主机(能否通)—尝试成功才会发送HTTP请求—发送到tomcat猫服务器—解析主机名(因为一个tomcat可以配置多个主机的)—再进行web应用解析(文件夹层)—解析资源名—获取(通过java代码)资源(html/jsp)—结果返回到浏览器—浏览器展示。
B.第一步设置hosts 127.0.0.1 wdfgdzx.com
C.第二步在server.xml中添加主机名
<Host name="wdfgdzx.com" appBase="webapps"
unpackWARs="true" autoDeploy="true"
xmlValidation="false" xmlNamespaceAware="false">
<Context path="/Hi" docBase="F:Hi"/>
</Host>
D.重新启动下猫就生效了,可以访问wdfgdzx.com了1.6Tomcat体系再说明
SERVER.XML
1.6.1SERVICE
1.6.1.1Engine(引擎)
A.主机—Context(web应用)
B.主机—Context(web应用)
1.6.2Connector
1.6.2.1HTTP协议
1.6.2.2HTTPS协议
1.6.3可以配置默认主机
1.6.3.1在SERVER.XML文件中
<Engine name="Catalina" defaultHost="localhost">
2.SERVLET的必要性
2.1需求
2.1.1发帖/回复/交互功能
2.1.1.1仅仅靠JAVA技术完成不了,SERVLET就应用而生
2.1.2SERVLET在WEB应用下的位置
2.1.2.1在WEB-INF的classes目录下
2.2SERVLET的快速入门案例
开发SERVLET有三种方式,第一种实现SERVLET接口,第二种通过继承GenericServlet,第三种通过继承HttpServlet
2.2.1通过实现Sservlet接口的方法,可以显示一句话Make Time For Dreams
2.2.1.1建立一个WEB应用
A.maven应用
B.在maven下建立WEB-INF/web.xml(可以从ROOT下的web.xml拷贝内容)
C.在WEB-INF下建立classes目录,我们的JAVA就要在这个目录下开发(Maven中是在target文件下)
D.再建立一个LIB文件用于引包(当然Maven不需要了)
2.2.1.2编写JAVA代码
package surface;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyFirstServlet implements Servlet {
//初始化,就是把此Servlet装载到内存中,只会被调用一次
public void init(ServletConfig arg0) throws ServletException {
}
//该函数是得到servletConfig对象
public ServletConfig getServletConfig() {
return null;
}
//核心函数service,该函数是服务函数,业务逻辑代码都写到这里
//每次请求都会调用
public void service(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
//System.out.println("Hi"+new java.util.Date());
response.getWriter().println("Hi "+new java.util.Date());
}
//得到该servlet的一些配置信息
public String getServletInfo() {
return null;
}
//销毁该servlet函数,从内存中清除,只会被调用一次
public void destroy() {
// TODO Auto-generated method stub}
}
2.2.1.3编写WEB.XML
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 根据servlet规范需要将servlet部署到web.xml以被查询,该部署配置可以从拷贝 -->
<servlet>
<!--名称,访问的时候是有用的,可以自定义,最好与java里面对应 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这个就需要明确指定该servlet放在哪个包下,形式是复制全路径粘贴,Ctrl单击就行了 -->
<servlet-class>surface.MyFirstServlet</servlet-class>
</servlet>
<!--servlet映射 -->
<servlet-mapping>
<!--这个要和上面第一个servlet-name哪个一致 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这里可以自定义,也可以写成MyFirstServlet -->
<url-pattern>/wdfgdzx</url-pattern>
</servlet-mapping>
</web-app>
2.2.1.4启动
Eclipse右击运行Run on server 然后自动启动本地8080端口了
2.2.1.5访问
http://localhost:8080/maven/wdfgdzx 就可以看到展示的内容了HiThu Sep 13 21:55:25 CST 2018
2.2.1.6报错
A.如果写成了<servlet-class>surface.MyFirstServlet</servlet-class>/报500错误
B.如果<servlet>和<servlet-mapping>里的<servlet-name>不一致/启动报错/访问报503错误
C.如果配置没问题访问网址书写错误回报404错误2.3SERVLET生命周期
2.3.1流程图
2.3.1.1详细流程图
http://localhost:8080/maven/MyFirstServlet—浏览器先解析主机名—查询hosts查询主机对应的IP地址—查到就继续/(查不到就到DNS服务器查)—
WEB服务器—先发送试探包给WEB服务器—试探成功就发送HTTP请求—WEB服务器解析出主机http://localhost:8080/—解析WEB应用maven—解析出资源名称MyFirstServlet—WEB服务器查询WEB.XML文件—WEB服务器使用反射机制创建MyFirstServlet.java实例—调用init方法将该实例装载到内存(该方法只调用一次/不管是不是一个浏览器/是不是一个IP/单例都只会调用一次)—WEB服务器把接受到的HTTP请求封装成Request对象,作为service方法的参数传入(会被调用多次/每访问一次就会被调用一次)—WEB服务器获取到Response结果对象(有各种信息)—WEB服务器把Response的信息拆解出来,形成HTTP响应格式—就是查尔斯获取的第二联的原始数据—浏览器拿到结果—进行展示—当在tomcat关闭/关机/reload情况下WEB服务器会调用servlet的destroy函数讲servlet销毁
2.3.2中文乱码解决
2.3.2.1统一设置成UTF-8
request.setCharacterEncoding("UTF-8");和response.setCharacterEncoding("UTF-8");/这个针对servlet就可以了/浏览器编码格式也设置成UTF-82.4使用继承HttpServlet的方法来开发servlet
2.4.1公司使用率90%以上
2.4.2举例说明
2.4.2.1代码明细
package surface;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyHttpServlet extends HttpServlet{
//设计者提供了对post和get提交分别处理
//回忆<form action=" " method="post/get" />默认是get提交
//其实doGet和doPost最终也去调用了service方法
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
//doPost(request,response);
response.getWriter().println("Hi I am is HttpServlet get");
}
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
response.getWriter().println("Hi I am is HttpServlet post");
}
}
2.4.2.2配置WEB.XML
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 根据servlet规范需要将servlet部署到web.xml以被查询,该部署配置可以从拷贝 -->
<servlet>
<!--名称,访问的时候是有用的,可以自定义,最好与java里面对应 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这个就需要明确指定该servlet放在哪个包下,形式是复制全路径粘贴,Ctrl单击就行了 -->
<servlet-class>surface.MyFirstServlet</servlet-class>
</servlet>
<!--servlet映射 -->
<servlet-mapping>
<!--这个要和上面第一个servlet-name哪个一致 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这里可以自定义,也可以写成MyFirstServlet /wdfgdzx -->
<url-pattern>/MyFirstServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>MyHttpServlet</servlet-name>
<servlet-class>surface.MyHttpServlet</servlet-class>
</servlet>
<!--servlet映射 -->
<servlet-mapping>
<servlet-name>MyHttpServlet</servlet-name>
<url-pattern>/MyHttpServlet</url-pattern>
</servlet-mapping>
</web-app>
2.4.2.3输入http://localhost:8080/maven/MyHttpServlet访问/默认的是get方法
2.4.2.4验证post方式提交/借助一个HTML文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<!--这里写get提交后将会在地址栏展示参数-->
<form action="http://localhost:8080/maven/MyHttpServlet" method="post">
<input type="text" value="爱好" name="love”/>
<input type="submit" value="提交"/>
</form>
</body>
</html>
访问后展示Hi I am is HttpServlet post
2.4.2.5取出用户输入的值进行展示
package surface;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyHttpServlet extends HttpServlet{
//设计者提供了对post和get提交分别处理
//回忆<form action=" " method="post/get" />默认是get提交
//其实doGet和doPost最终也去调用了service方法
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
//doPost(request,response);
response.getWriter().println("Hi I am is HttpServlet get");
}
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.getWriter().println("Hi I am is HttpServlet post");
response.getWriter().println(request.getParameter("love"));//肯定实际中要有love这name的参数
}
}
2.4.2.6两种提交方式的区别
A.安全性get<post
B.容量好get<post
C.请求速度get>post2.5使用Eclipse+Maven开发servlet/jsp/spring
2.5.1合二为一
2.5.1.1编写代码
package surface;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyHttpServlet extends HttpServlet{
//设计者提供了对post和get提交分别处理
//回忆<form action=" " method="post/get" />默认是get提交
//其实doGet和doPost最终也去调用了service方法
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
//doPost(request,response);
doPost(request,response);//两种方式合二为一
}
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.getWriter().println("Hi I am is HttpServlet post");
response.getWriter().println(request.getParameter("love"));
}
}
2.5.1.2配置tomcat猫
run as—run on server—Mannually define a new server—下一步选择tomcat实际存放目录—点击finish—可以选择下次默认启动该配置的猫。这样就完成了配置。
2.5.1.3发布在猫上即可/访问http://wdfgdzx.j2eeall.com/maven/MyHttpServlet
A.可能遇到的问题是服务器的jdk版本与java的不一致,注意保持一致!
3.Servlet细节
3.1配置文件详解
<servlet>
<!--名称,访问的时候是有用的,可以自定义,最好与java里面对应,servlet注册 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这个就需要明确指定该servlet放在哪个包下,形式是复制全路径粘贴不带java结尾,Ctrl单击就行了 -->
<servlet-class>surface.MyFirstServlet</servlet-class>
</servlet>
<!--servlet映射 ,已经注册的servlet的对外访问路径-->
<servlet-mapping>
<!--这个要和上面第一个servlet-name哪个一致 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这里可以自定义,也可以写成MyFirstServlet /wdfgdzx 这个是真正的访问路径-->
<url-pattern>/MyFirstServlet</url-pattern>
</servlet-mapping>
3.1.1可以多映射<servlet-mapping>到同一个servlet.java
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 根据servlet规范需要将servlet部署到web.xml以被查询,该部署配置可以从拷贝 -->
<servlet>
<!--名称,访问的时候是有用的,可以自定义,最好与java里面对应 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这个就需要明确指定该servlet放在哪个包下,形式是复制全路径粘贴,Ctrl单击就行了 -->
<servlet-class>surface.MyFirstServlet</servlet-class>
</servlet>
<!--servlet映射 -->
<servlet-mapping>
<!--这个要和上面第一个servlet-name哪个一致 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这里可以自定义,也可以写成MyFirstServlet /wdfgdzx -->
<url-pattern>/MyFirstServlet</url-pattern>
</servlet-mapping>
<servlet>
<!--名称,访问的时候是有用的,可以自定义,最好与java里面对应 -->
<servlet-name>MyHttpServlet</servlet-name>
<!--这个就需要明确指定该servlet放在哪个包下,形式是复制全路径粘贴,Ctrl单击就行了 -->
<servlet-class>surface.MyHttpServlet</servlet-class>
</servlet>
<!--servlet映射 -->
<servlet-mapping>
<!--这个要和上面第一个servlet-name哪个一致 -->
<servlet-name>MyHttpServlet</servlet-name>
<!--这里可以自定义,也可以写成MyFirstServlet /wdfgdzx -->
<url-pattern>/MyHttpServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<!--这个要和上面第一个servlet-name哪个一致 -->
<servlet-name>MyHttpServlet</servlet-name>
<!--这里可以自定义,也可以写成MyFirstServlet /wdfgdzx -->
<url-pattern>/wdfgdzx</url-pattern>
</servlet-mapping>
</web-app>
3.1.2允许多层映射/wdfgdzx/top也可以
3.1.3几种匹配模式
3.1.3.1第一种*.扩展名
3.1.3.2第二种/开头以/*结尾/比如/*或者是/News/*
3.1.3.3第三种匹配原则谁的匹配度高,优先取谁
例如wdfgdzx是/abc/*和wdfgdzxtop是/* 肯定是wdfgdzx被匹配上/ 优先级最低的是*.do3.2servlet类是由java引擎(WEB服务器)调用的java类/无法独立运行的
3.2.1servlet单例问题
3.2.1.1当servlet第一次被访问,就被加载到内存,以后该实例对各个请求进行服务,即在使用是中单例的。
3.2.1.2可能出现线程不安全的问题/这个程序联系访问三次就会在控制台打出三次买票
你买到票了!
你买到票了!
你买到票了!
package surface;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyHttpServlet extends HttpServlet{
//设计者提供了对post和get提交分别处理
//回忆<form action=" " method="post/get" />默认是get提交
//其实doGet和doPost最终也去调用了service方法
int i=2;
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
//doPost(request,response);
doPost(request,response);//两种方式合二为一
}
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//response.getWriter().println("Hi I am is HttpServlet post");
//response.getWriter().println("访问次数:"+i);
if(i>0){
System.out.println("你买到票了!");
try {
Thread.sleep(10*1000);//休眠10秒模拟高并发
i--;
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("你没有买到票!");
}
}
}
3.2.1.3问题解决方案
使用synchronized同步,不加就会出现问题。
你买到票了!
你买到票了!
你没有买到票!
你没有买到票!
package surface;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class MyHttpServlet extends HttpServlet{
//设计者提供了对post和get提交分别处理
//回忆<form action=" " method="post/get" />默认是get提交
//其实doGet和doPost最终也去调用了service方法
int i=2;
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
//doPost(request,response);
doPost(request,response);//两种方式合二为一
}
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
//response.getWriter().println("Hi I am is HttpServlet post");
//response.getWriter().println("访问次数:"+i);
//简单的解决方法
synchronized (this) {
if(i>0){
System.out.println("你买到票了!");
try {
Thread.sleep(10*1000);//休眠10秒模拟高并发
i--;
} catch (InterruptedException e) {
e.printStackTrace();
}
}else{
System.out.println("你没有买到票!");
}
}
}
}
3.2.1.4原则描述
A.如果一个变量需要多个用户共享,则应当在访问改变量的时候加同步机制。
B.如果一个变量不需要共享,不要定义成成员变量,在方法内定义即可。3.3网站启动时需要创建临时表
3.3.1网站要定时的完成一些任务/定时写日志/备份数据库
3.3.2邮件定时发送
3.3.3解决方法
3.3.3.1使用<load-on-startup>配置需求和线程知识就可以搞定
3.3.3.2写初始化函数和发放
package surface;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class MyInitServlet extends HttpServlet{
public void init() throws ServletException {
System.out.println("init函数被调用");
}
}
3.3.3.3配置web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 根据servlet规范需要将servlet部署到web.xml以被查询,该部署配置可以从拷贝 -->
<servlet>
<!--名称,访问的时候是有用的,可以自定义,最好与java里面对应 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这个就需要明确指定该servlet放在哪个包下,形式是复制全路径粘贴,Ctrl单击就行了 -->
<servlet-class>surface.MyFirstServlet</servlet-class>
</servlet>
<!--servlet映射 -->
<servlet-mapping>
<!--这个要和上面第一个servlet-name哪个一致 -->
<servlet-name>MyFirstServlet</servlet-name>
<!--这里可以自定义,也可以写成MyFirstServlet /wdfgdzx -->
<url-pattern>/MyFirstServlet</url-pattern>
</servlet-mapping>
<servlet>
<!--名称,访问的时候是有用的,可以自定义,最好与java里面对应 -->
<servlet-name>MyHttpServlet</servlet-name>
<!--这个就需要明确指定该servlet放在哪个包下,形式是复制全路径粘贴,Ctrl单击就行了 -->
<servlet-class>surface.MyHttpServlet</servlet-class>
</servlet>
<!--servlet映射 -->
<servlet-mapping>
<!--这个要和上面第一个servlet-name哪个一致 -->
<servlet-name>MyHttpServlet</servlet-name>
<!--这里可以自定义,也可以写成MyFirstServlet /wdfgdzx -->
<url-pattern>/MyHttpServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<!--这个要和上面第一个servlet-name哪个一致 -->
<servlet-name>MyHttpServlet</servlet-name>
<!--这里可以自定义,也可以写成MyFirstServlet /wdfgdzx -->
<url-pattern>/wdfgdzx</url-pattern>
</servlet-mapping>
<servlet>
<description>HIT</description>
<display-name>哈工大</display-name>
<servlet-name>MyInitServlet</servlet-name>
<servlet-class>surface.MyInitServlet</servlet-class>
<!-- 1表好被init调用的优先级 -->
<load-on-startup>1</load-on-startup>
</servlet>
</web-app>
3.3.3.4预备工作就可以在init方法中做了
A.如果有个ID/内容/定时发送时间表/用线程做到定时发送
B.线程代码
package pojo;
public class SendEmailThread extends Thread{
public void run() {
int i=0;
try{
while(true){//需要用到循环
//没休眠一分钟就取扫描下数据库表,看下那封信应该被发出
Thread.sleep(5*1000);//60就是一分钟
System.out.println("发出邮件"+(++i));
}
}catch(Exception e){
e.printStackTrace();
}
}
}
C.函数init启动线程
package surface;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import pojo.SendEmailThread;
public class MyInitServlet extends HttpServlet{
public void init() throws ServletException {
System.out.println("init函数被调用");
System.out.println("创建数据库并读取数据");
//创建一个线程
SendEmailThread sendEmailThread=new SendEmailThread();
sendEmailThread.start();//启动该线程
}
}
D.突然发现发送邮件存在顺序错乱,相同要用“森瑞那一次的synchronized”来做同步机制
E.该代码后果然解决
package pojo;
public class SendEmailThread extends Thread{
public void run() {
int i=0;
synchronized (this){
try{
while(true){//需要用到循环
//没休眠一分钟就取扫描下数据库表,看下那封信应该被发出
Thread.sleep(5*1000);//60就是一分钟
System.out.println("发出邮件"+(++i));
}
}catch(Exception e){
e.printStackTrace();
}
}
}
}3.4ServletConfig对象/用于读取servlet的配置信息
3.4.1配置信息片段WEB.XML
<servlet>
<description>HIT</description>
<display-name>哈工大</display-name>
<servlet-name>ServletConfig</servlet-name>
<servlet-class>surface.ServletConfig</servlet-class>
<!-- 这里可以给servlet配置信息 ,这里配置的信息只能被该servlet读取 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ServletConfig</servlet-name>
<url-pattern>/ServletConfig</url-pattern>
</servlet-mapping>
3.4.2方法中去使用代码
package surface;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletConfig extends HttpServlet{
public void init() throws ServletException {}
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
doPost(req,resp);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
String str=this.getServletConfig().getInitParameter("encoding");
resp.setCharacterEncoding(str);
resp.getWriter().println("编码是"+str);
}
}
3.4.3所有都去读取某个参数应该这么配置
<!-- 这里可以被多个servlet读取 -->
<!-- <context-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</context-param> -->
4.实际网站开发
4.1用户登录1.0版
4.1.1框架图
4.1.1.1说明有多少文件,以及他们之间的调用关系,以及层的关系
4.1.1.2登录界面LoginServlet—处理DealServlet—合法管理界面AdminServlet/不合法则返回登录界面
4.1.2登录界面
4.1.2.1写Login界面
4.1.2.2写Controler就是Deal控制器/接受数据/判断应该跳转到那个页面
4.1.2.3代码明细
A.登录界面代码
package surface;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Login extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//返回一个界面
resp.getWriter().println("<h1>用户登录</h1>");
resp.getWriter().println("<form action='/maven/Deal' method='post'>");
resp.getWriter().println("用户名称:<input type='text' name='username'/><br/>");
resp.getWriter().println("用户密码:<input type='password' name='password'/><br/>");
resp.getWriter().println("<input type='submit' value='登录'/><br/>");
resp.getWriter().println("</form>");
}
}
B.接受页面代码
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Deal extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//接受用户名和密码
String username=req.getParameter("username");
String password=req.getParameter("password");
System.out.println(username+" "+password);
}
}
C.配置WEB.XML明细
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 根据servlet规范需要将servlet部署到web.xml以被查询,该部署配置可以从拷贝 --><servlet>
<description>HIT</description>
<display-name>哈工大</display-name>
<servlet-name>ServletConfig</servlet-name>
<servlet-class>surface.ServletConfig</servlet-class>
<!-- 这里可以给servlet配置信息 ,这里配置的信息只能被该servlet读取 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ServletConfig</servlet-name>
<url-pattern>/ServletConfig</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>surface.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Deal</servlet-name>
<servlet-class>controller.Deal</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Deal</servlet-name>
<url-pattern>/Deal</url-pattern>
</servlet-mapping>
</web-app>
4.1.2.5管理界面和失败界面跳转
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Deal extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//接受用户名和密码
String username=req.getParameter("username");
String password=req.getParameter("password");
if(username.equals("liu19911009")&&password.equals("s5012280")){
//跳转/转向Sendredict和转发forword
resp.sendRedirect("/maven/Admin");
}else{
//跳回
resp.sendRedirect("/maven/Login");
}
}
}
4.1.2.6WEB.XML配置
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<!-- 根据servlet规范需要将servlet部署到web.xml以被查询,该部署配置可以从拷贝 -->
<servlet>
<description>HIT</description>
<display-name>哈工大</display-name>
<servlet-name>ServletConfig</servlet-name>
<servlet-class>surface.ServletConfig</servlet-class>
<!-- 这里可以给servlet配置信息 ,这里配置的信息只能被该servlet读取 -->
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ServletConfig</servlet-name>
<url-pattern>/ServletConfig</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Login</servlet-name>
<servlet-class>surface.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Deal</servlet-name>
<servlet-class>controller.Deal</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Deal</servlet-name>
<url-pattern>/Deal</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>surface.Admin</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/Admin</url-pattern>
</servlet-mapping>
</web-app>
4.1.3进一步写界面
4.1.3.1
package surface;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Admin extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//展示管理界面
resp.getWriter().println("<h1>管理员界面</h1>");
resp.getWriter().println("<a href='/maven/Login'>返回登录界面</a>");
}
}4.2深度剖析HTTP协议
4.2.1什么是HTTP协议
4.2.1.1是互联网应用最为广泛的协议/是工作在TCP/IP协议基础之上的
4.2.1.2全名称是超文本传输协议/有1.0的短连接和1.1的长连接/目前通用过得是1.1版本
4.2.1.3长短连接指的是持续的时间
4.2.2HTTP请求次数
4.2.2.1浏览器发出几次HTTP请求/三次
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>请求次数</title>
</head>
<body>
<h1>两幅图片</h1>
<img src="1.jpg" />
<img src="2.jpg" />
</body>
</html>
4.2.2.2完整的HTTP请求包括
A.请求行GET /maven/Request.html HTTP/1.1
B.消息头/消息名:内容/并不是每次请求都一样
Host: wdfgdzx.j2eeall.com
Content-Length: 38
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Origin: http://wdfgdzx.j2eeall.com
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) 
Chrome/49.0.2623.112 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Referer: http://wdfgdzx.j2eeall.com/maven/Login
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Content-Type: text/html;charset=UTF-8
Date: Sun, 16 Sep 2018 06:32:34 GMT
Connection: keep-alive
C.空行+内容username=liu19911009&password=s5012280
4.2.2.3请求方式get/post最常见
4.2.2.4详解消息头
A.Accept告诉服务器浏览器可以接收文件格式/Accept-Encoding: gzip, deflate可以接受压缩后数据
B.Accept-Language浏览器支持的语言/Host要找那个主机
C.Referer告诉服务器我来自哪里(改消息头常用于防止盗链/下载等)/User-Agent告诉服务器我的浏览器内核
D.Connection发完数后不关闭连接
4.2.3防止盗链/Referer实际案例
4.2.3.1代码明细
A.防盗链操作
package surface;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyRequest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//通过Requestl来获取http请求信息
//获取浏览器的Referer信息
String referer=req.getHeader("Referer");
//resp.getWriter().println(referer);
if(referer==null||!referer.startsWith("http://wdfgdzx.j2eeall.com/maven")){
resp.sendRedirect("/maven/Error");
return;
}
resp.getWriter().println(req.getHeader("Host"));
resp.getWriter().println("这是我们非常重要的信息账号123 密码321");
}
}
B.直接访问将会跳转报错页面
C.可以访问代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>请求次数</title>
</head>
<body>
<a href="http://wdfgdzx.j2eeall.com/maven/MyRequest">访问重要信息</a>
<h1>两幅图片</h1>
<img src="1.jpg" />
<img src="2.jpg" />
</body>
</html>4.3HTTP响应
4.3.1整体结构
4.3.1.1状态行—多个消息头—一个空行—内容
4.3.1.2详情
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=UTF-8
Date: Sun, 16 Sep 2018 07:41:52 GMT
content-encoding: gzip
Transfer-Encoding: chunked
Proxy-Connection: keep-alivelocalhost
这是我们非常重要的信息账号123 密码321
4.3.1.3状态行码有几种数字段/举例说明/200表示整个过程没有错误/302表示当你请求一个资源的时候,服务器让浏览器转向到另外一个资源
比如:resp.sendRedirect("/maven/Error");报HTTP/1.1 302 Moved Temporarily/404代表找不到资源HTTP/1.1 404 Not Found/
500表示服务器端出现错误了如:服务端有int i=9/0就会出现HTTP/1.1 500 Internal Server Error
4.3.1.4各个头的详解
A.Location重新定位到哪里去/Server告诉浏览器我是tomcat类型服务器
B.content-encoding告诉浏览器我是用gzip压缩的/Content-Type告诉浏览器服务器的文本和编码
C.Refresh过多久刷新到网址Refresh: 5;url=http://www.baidu.com
resp.setHeader("Refresh", "5;url=http://www.baidu.com");//5秒以后跳转到百度,写成自己可以定时刷新页面
D.Content-Disposition告诉浏览器有文件需要下载
package surface;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Down extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//演示下载文件
resp.setHeader("Content-Disposition", "attachment;filename=1.jpg");
//打开文件,说明一下web站点下载文件的原理,先读文件,再发送到浏览器
String path=this.getServletContext().getRealPath("1.jpg");//得到真实绝对路径
//创建文件输入流
FileInputStream fileInputStream=new FileInputStream(path);
//做一个缓冲字节数组
byte buff[]=new byte[1024];//当然也可以2048大点也可以的
int realReadLength=0;//realReadLength表示实际每次读取了多少个字节。
OutputStream outputStreamResult=resp.getOutputStream();
while((realReadLength=fileInputStream.read(buff))>0){
outputStreamResult.write(buff, 0, realReadLength);
}
//关闭流
outputStreamResult.close();
fileInputStream.close();
}
}
E.做一个简单的文件下载网站(点击下载就行了)/可以下载自己的教程了/卧槽/各种文件都可以做/加入防盗链下载
F.cookies后面有个章节详解
G.指定缓存/告诉浏览器如何缓存数据Expires/Cache-Control/Pragma
4.3.2缓存页面举例说明
4.3.2.1我们在浏览器默认的情况下,会缓存我们的页面。用户如果在地址栏回车,可能会从Cache中取数据/一些实时更新的网站是不允许
这么干的/要求我们不缓存页面。/怎么处理呢
4.3.2.2设置不缓存代码
package wdfgdzx;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class ResponseTest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//指定不缓存
//resp.setHeader(name,data);定时缓存多久
resp.setDateHeader("Expires", -1);
//保证兼容性
resp.setHeader("Cache-Control","no-cache");
resp.setHeader("Pragma", "no-cache");
//返回一个界面
resp.getWriter().println("Hi Company"+new java.util.Date());
}
}
4.3.2.3缓存一定时间(如一个小时)/resp.setDateHeader("Expires",System.一个函数);
4.3.3Connection/Keep-Alive现在基本都是长连接
4.4Servlet的三大改进
4.4.1HttpServletRequest和HttpServletResponse
4.4.1.1Request和Response对象代表请求和响应/所有的参数渗透从这两方面做工作即可/
A.Response的getWriter(回送文本)和getOutputStream(回送文件/当然也可以回送文本)方法/
getWriter回送字符/getOutputStream它可以回送字符,也可以回送字节(二进制)
B.代码举例
package wdfgdzx;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class ResponseTest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//resp.getWriter().println("Hi Company"+new java.util.Date());
resp.getOutputStream().write(("Hi Company"+new java.util.Date()+"字符转换成字节").getBytes());//使用一个方法即可
}
}
C.如何选择使用呢/如果回送字符数据使用getWriter效率高(当然使用getOutputStream也可以/知识效率低点)/如果回送字节(二进制)数据则只能使用getOutputStream/两种不能同时使用会报错的。内部500错误
D.为什么两个同时使用会报错呢。浏览器-服务器-Http类当服务器发现getWriter就会把内容封装到Response对象中返回给WEB服务器-
WEB服务器拆解response信息成http响应信息返回给浏览器/WEB服务器就会检测response相关的流是否已经关闭-如果没有关闭则 
帮你关闭/-关闭了再写肯定报错了。也可以看出为什么没有主动关闭流程序也没有问题的原因/提倡主动关闭更好了。
4.4.1.2SendRedirect实现重定向/并且可以带数据给下个页面
A.具体案例需求:带数据给下个页面提示该用户欢迎您
B.方案有很多:/static静态变量储存展示/使用SendRedirect:resp.sendRedirect("/maven/Admin?username="+username);转向第二个
页面的时候默认是get请求/界面展示resp.getWriter().println("<h1>管理员界面</h1>"+"欢迎您"+req.getParameter("username"));传多个
resp.sendRedirect("/maven/Admin?username="+username+"&content=");/如果传中文要做乱码处理/还有一种使用session传递信息的
方法预热下来/req.getSession().setAttribute("content", content);/String content=(String) req.getSession().getAttribute("content");//这种
方式的有点是什么,不仅可以传递子串,还可以传递对象。卧槽突然想到ModelAndView一样的
C.Session传递原理简单分析/浏览器-web服务器-tomcat管理的内容-session域分布在所有tomcat管理类-所以这个域内所有的管理内容都
可以使用/而且session域可以放多个值甚至对象,太牛逼了。/所有可以随想参数渗透和取值了
4.4.1.3中文乱码处理专题
A.发生乱码有三种情况:提价数据(表单提交(post/get))/超链接地址?参数=中文&参数=/SendRedirect发生乱码resp.sendRedirect("/maven/Admin?username=中文");
B.实际案例代码举例第一个
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>表单提交</title>
</head>
<body>
<form action="http://localhost/maven/GetInfoServlet" method="post">
账号:<input type="text" name="username"/>
<input type="submit" value="提交" />
</form>
</body>
</html>
类的代码
package encoding;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class GetInfoServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//resp.getWriter().println("Hi Company"+new java.util.Date());
resp.getWriter().write(req.getParameter("username"));
}
}
C.浏览器utf-8-WEB服务器(老外开发的ISO-8859-1接收的)-GetInfoServlet/针对post方法的解决方案是req.setCharacterEncoding("UTF-8");
/如果是get提交应该是单独的处理String temp=new String(req.getParameter("username").getBytes("ISO-8859-1"),"UTF-8");
D.超链接的本质其实是get请求所以也是可以通过String temp方案解决的,测试略。
E.SendRedirect发生乱码
package encoding;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class GetInfoServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//resp.getWriter().println("Hi Company"+new java.util.Date());
String temp=new String(req.getParameter("username").getBytes("ISO-8859-1"),"UTF-8");
//resp.getWriter().write(temp);
//接受到的数据传递给Welcome页面
String info=java.net.URLEncoder.encode(temp,"UTF-8");//urlEncode编码如果需要转向的化
resp.sendRedirect("/maven/Welcome?username="+info);
}
}
第二段代码
package encoding;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Welcome extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//resp.getWriter().println("Hi Company"+new java.util.Date());
String tempTwo=new String(req.getParameter("username").getBytes("ISO-8859-1"),"UTF-8");
resp.getWriter().println(tempTwo);
}
}
F.说明:我们应当尽量使用post方式提交/session也能够很好的避免乱码问题/在服务器端是中文,客户端乱码,就设置Response的编码就行了 
resp.setCharacterEncoding("UTF-8");/
4.4.1.4通过Response可以控制浏览器的行为(有文件需要下载/不要缓存文件)/生成随机验证码
4.4.1.5HttpServletRequest对象的细节/该对象表示浏览器的请求/当WEB服务器得到后封装到HttpServletRequest对象中—开发人员通过这个对象的发放可以获取客户的这些信息。
A如:.http://wdfgdzx.j2eeall.com/maven/GetRequest?username=liu19911009req.getQueryString();//?username=liu19911009这部分/该函数获取请求部分的数据就会得到username=liu19911009
B.各种获取参数的方法汇总
package request;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class GetRequest extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
String url=req.getRequestURL().toString();
resp.getWriter().println(url+"分隔开来");
String uri=req.getRequestURI();
resp.getWriter().println(uri+"分隔开来");
String queryString=req.getQueryString();//?username=liu19911009这部分
resp.getWriter().println(queryString+"分隔开来");
String remoteAddr=req.getRemoteAddr();//获取IP地址
resp.getWriter().println(remoteAddr+"分隔开来");
String remoteHost=req.getRemoteHost();//在DNS上注册才能打出主机名,否则就是IP地址了
resp.getWriter().println(remoteHost+"分隔开来");
int remotePort=req.getRemotePort();//客户的端口是随机选择的端口
int serverPort=req.getLocalPort();resp.getWriter().println("客户端端口"+remotePort+"服务器端口:"+serverPort+"分隔开来");
}
}
C.下载的时候如果提示的源文件名乱码要用UrlEncode来处理下即可。String info=java.net.URLEncoder.encode(temp,"UTF-8");//urlEncode编码如果需要转向的化。
D.获取所有请求的头数据。
package request;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Header extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//getHeader通过消息头来获取信息
String host=req.getHeader("Host");
resp.getWriter().println(host);
//getHeaderNames方法,整个http请求的消息全部打印,下面的代码就可以解决
Enumeration allMessage=req.getHeaderNames();
while(allMessage.hasMoreElements()){
//取出消息头的名字
String headerName=(String) allMessage.nextElement();
resp.getWriter().println(headerName+":"+req.getHeader(headerName));
}
}
}
E.如何获取用户提交的信息内容(通过表单提交的)
Form表单代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>表单提交</title>
</head>
<body>
<form action="http://localhost/maven/Header" method="post">
账号:<input type="text" name="username"/>
<br/>
性别:<input type="radio" name="sex" value="男" />男
<input type="radio" name="sex" value="女" />女
<br/>
爱好<input type="checkbox" name="love" value="音乐">音乐
<input type="checkbox" name="love" value="体育">体育
<input type="checkbox" name="love" value="旅游">旅游
<br/>
所在城市<select name="city">
<option value="合肥">合肥</option>
<option value="亳州">亳州</option>
<option value="上海">上海</option>
</select>
<br/>
个人介绍<textarea rows="10" cols="20" name="show">在此输入内容</textarea>
<br/>
提交照片<input type="file" name="photo"/>
<br/>
<input type="submit" value="提交" />
<br/>
<input type="hidden" name="buy" value="买的秘密武器" />
<br/>
</form>
</body>
</html>
具体接收的JAVA代码
package request;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Header extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.getWriter().println("姓名:"+req.getParameter("username")+" 性别:"+req.getParameter("sex"));
//注意这里是getParameterValues
String loves[]=req.getParameterValues("love");
resp.getWriter().println(" 爱好:");
if(loves!=null){
for(int i=0;i<loves.length;i++){
resp.getWriter().println(loves[i]+" ");
}
}
else{
resp.getWriter().println("没有选择爱好");
}
//如果有多个也要效仿爱好
resp.getWriter().println(" 所在城市:"+req.getParameter("city"));
resp.getWriter().println(" 个人介绍:"+req.getParameter("show"));
//文件
//hidden隐藏参数
resp.getWriter().println(" 隐藏参数:"+req.getParameter("buy"));
}
}
F.实现请求转发/WEB资源收到客户端的请求通知服务器去调用另外一个WEB资源处理/我们实现转发已有的是resp.sendRedirect/接下来
我们使用request的转向方法/
提交界面代码
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>表单提交</title>
</head>
<body>
<form action="http://localhost/maven/RequestForword" method="post">
账号:<input type="text" name="username"/>
<br/>
性别:<input type="radio" name="sex" value="男" />男
<input type="radio" name="sex" value="女" />女
<br/>
爱好<input type="checkbox" name="love" value="音乐">音乐
<input type="checkbox" name="love" value="体育">体育
<input type="checkbox" name="love" value="旅游">旅游
<br/>
所在城市<select name="city">
<option value="合肥">合肥</option>
<option value="亳州">亳州</option>
<option value="上海">上海</option>
</select>
<br/>
个人介绍<textarea rows="10" cols="20" name="show">在此输入内容</textarea>
<br/>
提交照片<input type="file" name="photo"/>
<br/>
<input type="submit" value="提交" />
<br/>
<input type="hidden" name="buy" value="买的秘密武器" />
<br/>
</form>
</body>
</html>
中间设置request参数wdfgdzx代码
package forword;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class RequestForword extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
req.setAttribute("wdfgdzx", "wdfgdzx");//添加了一个对象
//表示用转发的方法把request和response对象传递给下一个servlet对象
req.getRequestDispatcher("/RequestAdmin").forward(req, resp);
}
}
取出传递的username和设置的wdfgdzx参数
package forword;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class RequestAdmin extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//接受用户名
String username=req.getParameter("username");
resp.getWriter().println(username+req.getAttribute("wdfgdzx"));
}
}
//req属性放进去的生命周期是:在一次请求中有效/转向是在WEB服务器发生的所以写目录的时候少写了maven/response和request其实是
同一个对象/sendRedirect是发生在浏览器端的/getRequestDispatcher是WEB服务器端(所以如果转向百度肯定不行了,因为发生在服务端最前面自带maven)/使用sendRedirect不能通过request.setAttribute把属性传递给下一个servlet(因为sendRedirect发生在浏览器端)使得
request不是同一个了,所以取不出来Attribute,所以不能这么用/
G.什么是一次Http请求:/只要没有停止同时也没有重新回到浏览器重定向就算是一次请求。
H.地址栏地址停留在第一个转发的那个servlet网址url,比如上例就停留在http://localhost/maven/RequestForword
I.请求转发和请求重定向
4.4.2如何操作数据库
4.4.2.1到数据库中验证用户是否合法
A.使用my建立一个user表
B.写读取数据库的程序
必须把mysql-connector-java-5.1.7-bin.jar导入到tomcat的lib目录下面!/在java项目中,只需要引入mysql-connector-java-5.1.7-bin.jar就可以运行java项目。在web项目中,当Class.forName("om.mysql.jdbc.Driver");时myeclipse是不会去查找字符串,不会去查找驱动的。所以只需要把mysql-connector-java-5.1.7-bin.jar拷贝到tomcat下lib目录就可以了。
4.4.2.2数据库的知识耽误两天/
A.首先数据的连接再重申一下/connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/my", "root", "s5012280");//这里的my注意一下位置在哪里。/不是mysql而是my
B.关于数据库使用查询的参数第一种方法
Connection ct=null;Statement statement=null;
ResultSet resultSet=null;
statement=(Statement) ct.createStatement();
//拼接sql
String sql=“select *from user where username='”+username+"' and pssword='"+password+"'";
resultSet=statement.executeQuery(sql);//执行查询即可
while(resultSet.next()){System.out.println(resultSet.getObject("id"));}
C.还有一种方法
Connection connection=null;
ResultSet resultSet=null;
PreparedStatement preparedStatement=null;
preparedStatement=(PreparedStatement) connection.prepareStatement
("select *from user where username=? and password=?");
//给问号赋值
preparedStatement.setObject(1,username);
preparedStatement.setObject(2,password);
//4.执行操作
resultSet=preparedStatement.executeQuery();
while(resultSet.next()){System.out.println(resultSet.getObject("id"));}
D.具体操作数据库的代码/还有一个问题就是中文名称无法查询数据库
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/my?useUnicode=true&characterEncoding=UTF-8", 
"root", "s5012280");/这样就可以实现汉字也能查询了/界面输出乱码
E.使用System打印+设置编码的几种方式轻松搞定界面展示乱码的问题
4.4.2.3具体代码
A.登录界面
package surface;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Login extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//返回一个界面
resp.getWriter().println("<h1>用户登录</h1>");
resp.getWriter().println("<form action='/wdfgdzx/Controller' method='post'>");
resp.getWriter().println("用户名称:<input type='text' name='username'/><br/>");
resp.getWriter().println("用户密码:<input type='password' name='password'/><br/>");
resp.getWriter().println("<input type='submit' value='登录'/><br/>");
resp.getWriter().println("</form>");
}
}
B.控制界面(查询数据库界面)
package controller;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class Controller extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
Connection connection=null;
ResultSet resultSet=null;
PreparedStatement preparedStatement=null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");//加载驱动
//2.得到连接
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/my?useUnicode=true&characterEncoding=UTF-8", 
"root", "s5012280");
//3.预处理
preparedStatement=(PreparedStatement) connection.prepareStatement
("select *from user where username=? and password=?");
//给问号赋值
preparedStatement.setObject(1,username);
preparedStatement.setObject(2,password);
//4.执行操作
resultSet=preparedStatement.executeQuery();
//5.根据结果做处理
if(resultSet.next()) {
//说明该用户合法
System.out.println("查到数据库数值了---------");
System.out.println(req.getParameter("username"));
String info=java.net.URLEncoder.encode(req.getParameter("username"),"UTF-8");//urlEncode编码如果需要转向的化
System.out.println(info);
req.getRequestDispatcher("/Admin?username="+info).forward(req, resp);
}else{
req.getRequestDispatcher("/Login").forward(req, resp);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
if(resultSet!=null){
try{
resultSet.close();
}catch(Exception e){
e.printStackTrace();
}
resultSet=null;//垃圾回收
}
if(preparedStatement!=null){
try{
preparedStatement.close();
}catch(Exception e){
e.printStackTrace();
}
preparedStatement=null;//垃圾回收
}if(connection!=null){
try {
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
connection=null;
}}
}
}
C.管理员界面
package admin;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Admin extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//resp.getWriter().println("Hi Company"+new java.util.Date());
resp.getWriter().println("欢迎您首长同志:"+req.getParameter("username"));
}
}
D.web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>Controller</servlet-name>
<servlet-class>controller.Controller</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Controller</servlet-name>
<url-pattern>/Controller</url-pattern>
</servlet-mapping><servlet>
<servlet-name>Admin</servlet-name>
<servlet-class>admin.Admin</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Admin</servlet-name>
<url-pattern>/Admin</url-pattern>
</servlet-mapping><servlet>
<servlet-name>Login</servlet-name>
<servlet-class>surface.Login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Login</servlet-name>
<url-pattern>/Login</url-pattern>
</servlet-mapping></web-app>
E.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<groupId>wdfgdzx</groupId>
<artifactId>wdfgdzx</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>wdfgdzx Maven Webapp</name>
<!-- FIXME change it to the project's website -->
<url>http://www.example.com</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- servlet包 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
</dependencies>
<build>
<finalName>wdfgdzx</finalName>
<pluginManagement><!-- lock down plugins versions to avoid using Maven 
defaults (may be moved to parent pom) -->
<plugins>
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>3.0.0</version>
</plugin>
<!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.2</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.20.1</version>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.5.2</version>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.8.2</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
4.4.2.4用户名密码错误的提示
A.设置session
if(resultSet.next()) {
//说明该用户合法
System.out.println("查到数据库数值了---------");
//System.out.println(req.getParameter("username"));
String info=java.net.URLEncoder.encode(req.getParameter("username"),"UTF-8");//urlEncode编码如果需要转向的化
//System.out.println(info);
req.getRequestDispatcher("/Admin?username="+info).forward(req, resp);
}else{
req.setAttribute("err", "用户名或者密码错误");
req.getRequestDispatcher("/Login").forward(req, resp);
}
B.登录界面展示session/非空要加上,不然直接访问http://localhost/wdfgdzx/Login的时候展示什么呢。
if(req.getAttribute("err")!=null){
resp.getWriter().println("<font color='red'>"+req.getAttribute("err").toString()+"</font>");
}
4.4.2.5界面优化
A.管理界面
package admin;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Admin extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//resp.getWriter().println("Hi Company"+new java.util.Date());
resp.getWriter().println("欢迎您首长同志:"+req.getParameter("username"));
resp.getWriter().println("<a href='/wdfgdzx/Login'>返回登录界面</a>");
resp.getWriter().println("<h3>请选择操作</h3>");
resp.getWriter().println("<a href='/wdfgdzx/AdminUser'>管理用户</a>");
resp.getWriter().println("<a href='localhost/wdfgdzx/Login'>添加用户</a>");
resp.getWriter().println("<a href='localhost/wdfgdzx/Login'>查找用户</a>");
resp.getWriter().println("<a href='localhost/wdfgdzx/Login'>退出系统</a>");
}
}
B.管理用户跳转
package admin;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class AdminUser extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
Connection connection=null;
ResultSet resultSet=null;
PreparedStatement preparedStatement=null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");//加载驱动
//2.得到连接
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/my?useUnicode=true&characterEncoding=UTF-8",
"root", "s5012280");
//3.预处理
preparedStatement=(PreparedStatement) connection.prepareStatement
("select *from user");
//给问号赋值
/*preparedStatement.setObject(1,username);
preparedStatement.setObject(2,password);*/
//4.执行操作
resultSet=preparedStatement.executeQuery();
//查询数据库
resp.getWriter().println("<table border='1' width='500px' cellspacing='0'>");
resp.getWriter().println("<tr><td>id</td><td>用户名</td><td>email</td><td>级别</td></tr>");
while(resultSet.next()){
resp.getWriter().println("<tr><td>"+resultSet.getObject("id")+"</td>"
+ "<td>"+resultSet.getObject("username")+"</td>"
+ "<td>"+resultSet.getObject("email")+"</td>"
+ "<td>"+resultSet.getObject("level")+"</td></tr>");
}
resp.getWriter().println("<table>");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
if(resultSet!=null){
try{
resultSet.close();
}catch(Exception e){
e.printStackTrace();
}
resultSet=null;//垃圾回收
}
if(preparedStatement!=null){
try{
preparedStatement.close();
}catch(Exception e){
e.printStackTrace();
}
preparedStatement=null;//垃圾回收
}
if(connection!=null){
try {
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
connection=null;
}}
}
}
4.5技术深入优化
4.5.1如何在servlet中展示图片
4.5.1.1首先在webapp下新建Image文件夹专门放图片/这里写了1和2两个图片
A.修改后登录界面
package surface;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Login extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//返回一个界面
resp.getWriter().println("<img src='Image/1.jpg'><hr/>");
resp.getWriter().println("<h1>用户登录</h1>");
resp.getWriter().println("<form action='/wdfgdzx/Controller' method='post'>");
resp.getWriter().println("用户名称:<input type='text' name='username'/><br/>");
resp.getWriter().println("用户密码:<input type='password' name='password'/><br/>");
resp.getWriter().println("<input type='submit' value='登录'/><br/>");
resp.getWriter().println("</form>");
if(req.getAttribute("err")!=null){
resp.getWriter().println("<font color='red'>"+req.getAttribute("err").toString()+"</font>");
}
resp.getWriter().println("<hr/><img src='Image/2.jpg'>");
}
}
B.控制层
package controller;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class Controller extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
Connection connection=null;
ResultSet resultSet=null;
PreparedStatement preparedStatement=null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");//加载驱动
//2.得到连接
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/my?useUnicode=true&characterEncoding=UTF-8", 
"root", "s5012280");
//3.预处理
preparedStatement=(PreparedStatement) connection.prepareStatement
("select *from user where username=? and password=?");
//给问号赋值
preparedStatement.setObject(1,username);
preparedStatement.setObject(2,password);
//4.执行操作
resultSet=preparedStatement.executeQuery();
//5.根据结果做处理
if(resultSet.next()) {
//说明该用户合法
System.out.println("查到数据库数值了---------");
//System.out.println(req.getParameter("username"));
String info=java.net.URLEncoder.encode(req.getParameter("username"),"UTF-8");//urlEncode编码如果需要转向的化
//System.out.println(info);
req.getRequestDispatcher("/Admin?username="+info).forward(req, resp);
}else{
req.setAttribute("err", "用户名或者密码错误");
req.getRequestDispatcher("/Login").forward(req, resp);
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
if(resultSet!=null){
try{
resultSet.close();
}catch(Exception e){
e.printStackTrace();
}
resultSet=null;//垃圾回收
}
if(preparedStatement!=null){
try{
preparedStatement.close();
}catch(Exception e){
e.printStackTrace();
}
preparedStatement=null;//垃圾回收
}
if(connection!=null){
try {
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
connection=null;
}}
}
}
C.管理主界面
package admin;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Admin extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//resp.getWriter().println("Hi Company"+new java.util.Date());
resp.getWriter().println("<img src='Image/3.png'>"+"欢迎您首长同志:"+req.getParameter("username")
+"&nbsp&nbsp<a href='/wdfgdzx/Login'>返回登录界面</a>"+"<hr/>");
resp.getWriter().println("<h3>请选择操作</h3>");
resp.getWriter().println("<a href='/wdfgdzx/AdminUser'>管理用户</a><br/>");
resp.getWriter().println("<a href='localhost/wdfgdzx/Login'>添加用户</a><br/>");
resp.getWriter().println("<a href='localhost/wdfgdzx/Login'>查找用户</a><br/>");
resp.getWriter().println("<a href='localhost/wdfgdzx/Login'>退出系统</a><br/>");
resp.getWriter().println("<hr/><img src='Image/4.png'>");
}
}
D.管理用户界面
package admin;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class AdminUser extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
Connection connection=null;
ResultSet resultSet=null;
PreparedStatement preparedStatement=null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");//加载驱动
//2.得到连接
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/my?useUnicode=true&characterEncoding=UTF-8", 
"root", "s5012280");
//3.预处理
preparedStatement=(PreparedStatement) connection.prepareStatement
("select *from user");
//给问号赋值
/*preparedStatement.setObject(1,username);
preparedStatement.setObject(2,password);*///4.执行操作
resultSet=preparedStatement.executeQuery();
//查询数据库
resp.getWriter().println("<img src='Image/3.png'>"
+"欢迎您首长同志:"+req.getParameter("username")
+"<a href='/wdfgdzx/Admin'>返回主界面</a>"
+"&nbsp&nbsp&nbsp<a href='/wdfgdzx/Login'>安全退出</a>"
+ "<hr/>");
resp.getWriter().println("<table border='1' width='500px' cellspacing='0'>");
resp.getWriter().println("<tr><td>id</td><td>用户名</td><td>email</td><td>级别</td></tr>");
while(resultSet.next()){
resp.getWriter().println("<tr><td>"+resultSet.getObject("id")+"</td>"
+ "<td>"+resultSet.getObject("username")+"</td>"
+ "<td>"+resultSet.getObject("email")+"</td>"
+ "<td>"+resultSet.getObject("level")+"</td></tr>");
}
resp.getWriter().println("<table>");
resp.getWriter().println("<hr/><img src='Image/4.png'>");
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
if(resultSet!=null){
try{
resultSet.close();
}catch(Exception e){
e.printStackTrace();
}
resultSet=null;//垃圾回收
}
if(preparedStatement!=null){
try{
preparedStatement.close();
}catch(Exception e){
e.printStackTrace();
}
preparedStatement=null;//垃圾回收
}
if(connection!=null){
try {
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
connection=null;
}}
}
}
4.5.2分页技术详解
4.5.2.1思路/定义四个变量/nowPage当前页/totalPage总共多少页/perNumber每页显示多少条/totalNumber共有多少条记录/
nowPage用户决定的经常变化/perNumber是我们程序员指定的/totalNumber查的数据库/totalPage计算出来的
4.5.2.2计算总数totalNumber的思路。
if(totalNumber%perNumber==0){
totalPage=totalNumber/perNumber;
}else{
totalPage=totalNumber/perNumber+1;
}
简化的写法是: totalPage= (totalNumber-1)/perNumber +1;//这个有意思了
4.5.2.3完整的分页知识
A.查询指定的数据库条数/
select *from user where id<=6 and id>=4;
select *from user where id<="+perNumber*nowPage+" and id>="+(perNumber*(nowPage-1)+1)+";//活
B.查询数据库总共有多少条数据select count(*) from user;
C.分页AdminUser核心代码
package admin;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class AdminUser extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
Connection connection=null;
ResultSet resultSet=null;
PreparedStatement preparedStatement=null;
//定义分页需要的变量
int nowPage=1;
//接受传过来的nowPage,并且判断非空
if(req.getParameter("nowPage")!=null){
nowPage=Integer.parseInt(req.getParameter("nowPage"));//String转成int方法Integer.parseInt(str);
}
int perNumber=3;
int totalNumber=1;//查数据库得到的
int totalPage=2;//计算出来的
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");//加载驱动
//2.得到连接
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/my?useUnicode=true&characterEncoding=UTF-8", 
"root", "s5012280");
//算出共有多少页1.查询数据库有总共有多少
preparedStatement=(PreparedStatement) connection.prepareStatement("select count(*) from user");
resultSet=preparedStatement.executeQuery();
resultSet.next();
totalNumber=resultSet.getInt(1);//得到查询总数
if(totalNumber%perNumber==0){
totalPage=totalNumber/perNumber;
}else{
totalPage=totalNumber/perNumber+1;
}
//3.预处理
//大家思考
preparedStatement=(PreparedStatement) connection.prepareStatement
("select *from user where id<="+perNumber*nowPage+" and id>="+(perNumber*(nowPage-1)+1)+";");
//给问号赋值
/*preparedStatement.setObject(1,username);
preparedStatement.setObject(2,password);*///4.执行操作
resultSet=preparedStatement.executeQuery();
//查询数据库
resp.getWriter().println("<img src='Image/3.png'>"
+"欢迎您首长同志:"+req.getParameter("username")
+"<a href='/wdfgdzx/Admin'>返回主界面</a>"
+"&nbsp&nbsp&nbsp<a href='/wdfgdzx/Login'>安全退出</a>"
+ "<hr/>");
resp.getWriter().println("<table border='1' width='500px' cellspacing='0'>");
resp.getWriter().println("<tr><td>id</td><td>用户名</td><td>email</td><td>级别</td></tr>");
while(resultSet.next()){
resp.getWriter().println("<tr><td>"+resultSet.getObject("id")+"</td>"
+ "<td>"+resultSet.getObject("username")+"</td>"
+ "<td>"+resultSet.getObject("email")+"</td>"
+ "<td>"+resultSet.getObject("level")+"</td></tr>");
}
resp.getWriter().println("<table>");
//显示分页
for(int i=1;i<=totalPage;i++){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+i+"'><"+i+"></a>&nbsp");
}
resp.getWriter().println("<hr/><img src='Image/4.png'>"); 
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
if(resultSet!=null){
try{
resultSet.close();
}catch(Exception e){
e.printStackTrace();
}
resultSet=null;//垃圾回收
}
if(preparedStatement!=null){
try{
preparedStatement.close();
}catch(Exception e){
e.printStackTrace();
}
preparedStatement=null;//垃圾回收
}
if(connection!=null){
try {
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
connection=null;
}}
}
}
D.进一步优化分页和展示以及跳转[JS可以]核心代码
package admin;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class AdminUser extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
Connection connection=null;
ResultSet resultSet=null;
PreparedStatement preparedStatement=null;
//定义分页需要的变量
int nowPage=1;
//接受传过来的nowPage,并且判断非空
if(req.getParameter("nowPage")!=null){
nowPage=Integer.parseInt(req.getParameter("nowPage"));//String转成int方法Integer.parseInt(str);
}
int perNumber=3;
int totalNumber=1;//查数据库得到的
int totalPage=2;//计算出来的
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");//加载驱动
//2.得到连接
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/my?useUnicode=true&characterEncoding=UTF-8", 
"root", "s5012280");
//算出共有多少页1.查询数据库有总共有多少
preparedStatement=(PreparedStatement) connection.prepareStatement("select count(*) from user");
resultSet=preparedStatement.executeQuery();
resultSet.next();
totalNumber=resultSet.getInt(1);//得到查询总数
if(totalNumber%perNumber==0){
totalPage=totalNumber/perNumber;
}else{
totalPage=totalNumber/perNumber+1;
}//3.预处理
//大家思考
preparedStatement=(PreparedStatement) connection.prepareStatement
("select *from user where id<="+perNumber*nowPage+" and id>="+(perNumber*(nowPage-1)+1)+";");
//给问号赋值
/*preparedStatement.setObject(1,username);
preparedStatement.setObject(2,password);*/
//4.执行操作
resultSet=preparedStatement.executeQuery();
//js
resp.getWriter().println("<script type='text/javascript'>");
resp.getWriter().println("function goPage() {var nowPageTemp=document.getElementById('nowPage').value;"
+ "window.open('/wdfgdzx/AdminUser?nowPage='+nowPageTemp,'_self');}");
resp.getWriter().println("</script>");
//resp.getWriter().println("");
//查询数据库
resp.getWriter().println("<img src='Image/3.png'>"
+"欢迎您首长同志:"+req.getParameter("username")
+"<a href='/wdfgdzx/Admin'>返回主界面</a>"
+"&nbsp&nbsp&nbsp<a href='/wdfgdzx/Login'>安全退出</a>"
+ "<hr/>");
resp.getWriter().println("<table border='1' width='500px' cellspacing='0'>");
resp.getWriter().println("<tr><td>id</td><td>用户名</td><td>email</td><td>级别</td></tr>");
while(resultSet.next()){
resp.getWriter().println("<tr><td>"+resultSet.getObject("id")+"</td>"
+ "<td>"+resultSet.getObject("username")+"</td>"
+ "<td>"+resultSet.getObject("email")+"</td>"
+ "<td>"+resultSet.getObject("level")+"</td></tr>");
}
resp.getWriter().println("<table>");
resp.getWriter().println("<br/>");
//显示分页
if(nowPage!=1){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+(nowPage-1)+"'>上一页</a>&nbsp");
}
for(int i=1;i<=totalPage;i++){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+i+"'><"+i+"></a>&nbsp");
}
if(nowPage!=totalPage){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+(nowPage+1)+"'>下一页</a>&nbsp");
}
//显示分页信息
resp.getWriter().println("&nbsp当前页"+nowPage+"/总页数"+totalPage);
resp.getWriter().println("<br/>");
resp.getWriter().println("跳转到第<input type='text' name='nowPage' id='nowPage'/>"
+ "<input type='button' value='GO' οnclick='goPage()'");
resp.getWriter().println("<br/>");
resp.getWriter().println("<hr/><img src='Image/4.png'>"); 
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
if(resultSet!=null){
try{
resultSet.close();
}catch(Exception e){
e.printStackTrace();
}
resultSet=null;//垃圾回收
}
if(preparedStatement!=null){
try{
preparedStatement.close();
}catch(Exception e){
e.printStackTrace();
}
preparedStatement=null;//垃圾回收
}
if(connection!=null){
try {
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
connection=null;
}}
}
}
E.思考题:下我们只展示10个页面<< 12345678910 >>点这个翻10页/<<这个就是展示前10页
如何控制直接输入跳转页过大的问题。
4.5.4网站框架改进
4.5.4.1存在的问题登录层和管理层都去查了数据库,逻辑相似,代码重复/层次不清晰/代码可读性和可维护性差/
A.改进方案:进行分层使用MV模式(业务逻辑和界面代码分离) /-将常用代码封装到类中帮助工具类/-目的是减少代码重复,优化代码。
B.具体方法:每一张表对应一个java对象(pojo类)-还要对应一个service类。比如user对应一个User类和UserService类(该类会封装
对User表的各种操作。)-实际体现出的是数据和操作分离的思想。M V C的概念-模型业务逻辑(dao即util层/持久层)这三个层任意组合或者
只使用一个层都可以 / 视图界面 /控制层
4.5.4.2分层的操作
A.Service层
package service;
import java.sql.DriverManager;
import java.sql.ResultSet;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import pojo.User;
public class UserService {
//验证用户是否合法的函数
public boolean checkUser(User user){
boolean flag=false;
Connection connection=null;
ResultSet resultSet=null;
PreparedStatement preparedStatement=null;
try {
//1.加载驱动
Class.forName("com.mysql.jdbc.Driver");//加载驱动
//2.得到连接
connection=(Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/my"
+ "?useUnicode=true&characterEncoding=UTF-8", "root", "s5012280");
//3.预处理
preparedStatement=(PreparedStatement) connection.prepareStatement
("select *from user where username=? and password=?");
//给问号赋值
preparedStatement.setObject(1,user.getUsername());
preparedStatement.setObject(2,user.getPassword());
//4.执行操作
resultSet=preparedStatement.executeQuery();
//5.根据结果做处理
if(resultSet.next()){
flag=true;
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}finally{
if(resultSet!=null){
try{
resultSet.close();
}catch(Exception e){
e.printStackTrace();
}
resultSet=null;//垃圾回收
}
if(preparedStatement!=null){
try{
preparedStatement.close();
}catch(Exception e){
e.printStackTrace();
}
preparedStatement=null;//垃圾回收
}
if(connection!=null){
try {
connection.close();
} catch (Exception e) {
e.printStackTrace();
}
connection=null;
}
}
return flag;
}
}
B.Controller层分层后
package controller;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pojo.User;
import service.UserService;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class Controller extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
//创建UserService对象,完成到数据库的验证
UserService userService=new UserService();
User user=new User();
user.setUsername(username);
user.setPassword(password);
if(userService.checkUser(user)) {
String info=java.net.URLEncoder.encode(req.getParameter("username"),"UTF-8");//urlEncode编码如果需要转向的化
req.getRequestDispatcher("/Admin?username="+info).forward(req, resp);
}else{
req.setAttribute("err", "用户名或者密码错误");
req.getRequestDispatcher("/Login").forward(req, resp);
}
}
}
C.但是发现分层后,UserService也会有很多重复的代码-所以引出重复代码再次提炼到常用工具类实现/工具类也是属于model类的-
工具类就是DAO层
4.5.4.3工具类抽出来以后的代码
A.SqlHelper类代码
package util;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;import com.mysql.jdbc.CallableStatement;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import com.mysql.jdbc.Statement;
//操作数据库的工具类
public class SqlHelper {
private static Connection connection=null;
//使用preparedStatement代替statement防止sql注入
private static PreparedStatement preparedStatement=null;
private static ResultSet resultSet=null;
private static CallableStatement callableStatement=null;
public static PreparedStatement getPreparedStatement() {
return preparedStatement;
}
public static void setPreparedStatement(PreparedStatement preparedStatement) {
SqlHelper.preparedStatement = preparedStatement;
}
public static ResultSet getResultSet() {
return resultSet;
}
public static void setResultSet(ResultSet resultSet) {
SqlHelper.resultSet = resultSet;
}
public static CallableStatement getCallableStatement() {
return callableStatement;
}
public static void setCallableStatement(CallableStatement callableStatement) {
SqlHelper.callableStatement = callableStatement;
}
public static void setConnection(Connection connection) {
SqlHelper.connection = connection;
}
/*连接数据库参数*/
private static String url="";
private static String userName="";
private static String driver="";//" "这个是初始化用的,否则无法赋值
private static String password="";
//读取配置文件的
private static Properties properties=null;
private static FileInputStream fileInputStream=null;
//加载驱动,只需要一次就可以了
static{
try {
properties=new Properties();
//tomcat默认主目录在什么地方?是在安装的bin目录下?怎么解决呢
//根据一个方法获得系统路径,动态指定文件位置
String tomcatPath=Thread.currentThread().getContextClassLoader().getResource("").getPath();
//System.err.println(tomcatPath);
tomcatPath=tomcatPath.replaceAll("/.metadata/.plugins/org.eclipse.wst.server.core/tmp1/wtpwebapps/wdfgdzx/WEB-INF/classes/","");
//System.out.println(tomcatPath);
fileInputStream=new FileInputStream(tomcatPath+"/wdfgdzx/src/main/resources/properties");
properties.load(fileInputStream);//这里是不是少一步 赋值的 怎么赋值
url = properties.getProperty("jdbc.url");//是根据配置文件里定义形式来获取的
userName=properties.getProperty("jdbc.username"); 
password=properties.getProperty("jdbc.password");
driver=properties.getProperty("jdbc.driver");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
}
finally{
try {
fileInputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
fileInputStream=null;
}
}
/* 得到连接*/
public static Connection getConnection(){
try {
connection=(Connection) DriverManager.getConnection(url, userName, password);
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
/* 提供方法insert delete update select*/
public void executeInsert(){}
public void executeDelete(){}
/*sql格式:update 表明 set 字段名=? where字段=?
args应该是{"abc","23"}
如果有一次多种修改操作就写个二*/
public static void executeUpdate2(String []sql,String[][]args){
try{
connection=getConnection();
connection.setAutoCommit(false);
for(int i=0;i<sql.length;i++){
if(args[i]!=null){
preparedStatement=(PreparedStatement) connection.prepareStatement(sql[i]);
for(int j=0;j<args[i].length;j++){
/*循环的赋值*/
preparedStatement.setObject(j+1, args[i][j]);
}
preparedStatement.executeUpdate();
}
}
connection.commit();
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}finally{
close(connection, preparedStatement, resultSet);
}
}
public static void executeUpdate(String sql,String[]args){
connection=getConnection();
try {
/*System.out.println((PreparedStatement) ct.prepareStatement(sql));*/
preparedStatement=(PreparedStatement) connection.prepareStatement(sql);
/*System.out.println(psm);//
给?好赋值*/
if(args!=null){
/*看前后psm的值这个循环的作用就不言而预了*/
for(int i=0;i<args.length;i++){
preparedStatement.setString(i+1, args[i]);
}
/*System.out.println(psm);*/
}
/*执行*/
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
finally{
close(connection, preparedStatement, resultSet);/*关闭资源函数 */
}
}
public static ResultSet executeSelect(String sql,String args[]){
try{
connection=getConnection();
preparedStatement=(PreparedStatement) connection.prepareStatement(sql);
if(args!=null&&!args.equals("")){
for(int i=0;i<args.length;i++){
preparedStatement.setString(i+1, args[i]);
}
}
resultSet=preparedStatement.executeQuery();
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}finally{
/*close(ct,psm,rs);*/
}
return resultSet;
}
/*分页问题*/
public static ResultSet executeSelect(String sql[],String args[][]){return null;
}
/*调用储存过程*/
public static void executeSelect2(String sql,String inargs[],Integer outargs[]){
try{
connection=getConnection();
callableStatement=(CallableStatement) connection.prepareCall(sql);
if(inargs!=null){
for(int i=0;i<inargs.length;i++){
callableStatement.setObject(i+1, inargs[i]);
}
}
if(outargs!=null){
for(int i=0;i<outargs.length;i++){
callableStatement.registerOutParameter(inargs.length+1+i, outargs[i]);
}
}
callableStatement.executeQuery();
}catch(Exception e){
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}finally{
/* close(ct,cs,rs);*/
}
}
/*写关闭资源函数*/
public static void close(Connection ct,Statement psm,ResultSet rs){
if(psm!=null){
try{
psm.close();
}catch(Exception e){
e.printStackTrace();
}
psm=null;/*垃圾回收*/
}
if(ct!=null){
try {
ct.close();
} catch (SQLException e) {
e.printStackTrace();
}
connection=null;
}
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
B.抽离后的UserService层
package service;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import pojo.User;
import util.SqlHelper;
public class UserService {
//验证用户是否合法的函数
public boolean checkUser(User user){
boolean flag=false;
//使用SqlHelper来执行任务
//获取必要参数
String sql="select *from user where username=? and password=?";
String parameters[]={user.getUsername(),user.getPassword()};
//执行工具类
ResultSet resultSet=SqlHelper.executeSelect(sql,parameters);
//判断
try {
if(resultSet.next()){
flag=true;
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return flag;
}
}
C.控制层没有变
package controller;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pojo.User;
import service.UserService;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class Controller extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
//创建UserService对象,完成到数据库的验证
UserService userService=new UserService();
User user=new User();
user.setUsername(username);
user.setPassword(password);
if(userService.checkUser(user)) {
String info=java.net.URLEncoder.encode(req.getParameter("username"),"UTF-8");//urlEncode编码如果需要转向的化
req.getRequestDispatcher("/Admin?username="+info).forward(req, resp);
}else{
req.setAttribute("err", "用户名或者密码错误");
req.getRequestDispatcher("/Login").forward(req, resp);
}
}
}
D.阶段代码
4.5.4.4思路MVC的继续优化
A.说M用于后台,主要提供对业务的操作和数据。/V就是界面,用于显示数据。/C接受用户的请求(数据),然后去调用M的Service类
,然后根据执行的结果决定跳转到那个V去。
B.//按照分页来获取用户-//公司把ResultSet—取成User对象—再把对象放到一个集合里面去ArrayList(集合)—有两点好处,一个是封装
成对象get方法有实际的意思。二是封装到集合后,能够及时的关闭ResultSet释放数据库资源。
C.改了之后的AdminUser代码
package admin;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pojo.User;
import service.UserService;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class AdminUser extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//js
resp.getWriter().println("<script type='text/javascript'>");
resp.getWriter().println("function goPage() {var nowPageTemp=document.getElementById('nowPage').value;"
+ "window.open('/wdfgdzx/AdminUser?nowPage='+nowPageTemp,'_self');}");
resp.getWriter().println("</script>");
//resp.getWriter().println("");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
//定义分页需要的变量
int nowPage=1;
//接受传过来的nowPage,并且判断非空
if(req.getParameter("nowPage")!=null){
nowPage=Integer.parseInt(req.getParameter("nowPage"));//String转成int方法Integer.parseInt(str);
}
int perNumber=3;//每页展示多少
int totalPage=1;//计算出来的
try {
UserService userService=new UserService();
totalPage=userService.getTotalPage(perNumber);
ArrayList<User> userArrayList=userService.getUserByPage(nowPage, perNumber);
//查询数据库
resp.getWriter().println("<img src='Image/3.png'>"
+"欢迎您首长同志:"+req.getParameter("username")
+"<a href='/wdfgdzx/Admin'>返回主界面</a>"
+"&nbsp&nbsp&nbsp<a href='/wdfgdzx/Login'>安全退出</a>"
+ "<hr/>");
resp.getWriter().println("<table border='1' width='500px' cellspacing='0'>");
resp.getWriter().println("<tr><td>id</td><td>用户名</td><td>email</td><td>级别</td></tr>");
for(User user:userArrayList){
resp.getWriter().println("<tr><td>"+user.getId()+"</td>"
+ "<td>"+user.getUsername()+"</td>"
+ "<td>"+user.getEmail()+"</td>"
+ "<td>"+user.getLevel()+"</td></tr>");
}
resp.getWriter().println("<table>");
resp.getWriter().println("<br/>");
//显示分页
if(nowPage!=1){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+(nowPage-1)+"'>上一页</a>&nbsp");
}
for(int i=1;i<=totalPage;i++){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+i+"'><"+i+"></a>&nbsp");
}
if(nowPage!=totalPage){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+(nowPage+1)+"'>下一页</a>&nbsp");
}
//显示分页信息
resp.getWriter().println("&nbsp当前页"+nowPage+"/总页数"+totalPage);
resp.getWriter().println("<br/>");
resp.getWriter().println("跳转到第<input type='text' name='nowPage' id='nowPage'/>"
+ "<input type='button' value='GO' οnclick='goPage()'");
resp.getWriter().println("<br/>");
resp.getWriter().println("<hr/><img src='Image/4.png'>"); 
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
D.改制后的UserService代码
package service;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import pojo.User;
import util.SqlHelper;
public class UserService {
//验证用户是否合法的函数
public boolean checkUser(User user){
boolean flag=false;
//使用SqlHelper来执行任务
//获取必要参数
String sql="select *from user where username=? and password=?";
String parameters[]={user.getUsername(),user.getPassword()};
//执行工具类
ResultSet resultSet=SqlHelper.executeSelect(sql,parameters);
//判断
try {
if(resultSet.next()){
flag=true;
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return flag;
}//按照分页来获取用户
//公司把ResultSet—取成User对象—再把对象放到一个集合里面去ArrayList(集合)
public ArrayList getUserByPage(int nowPage,int perNumber){
ArrayList<User> userArrayList=new ArrayList<User>();
//查询语句
String sql="select *from user where id<="+perNumber*nowPage+" and id>="+(perNumber*(nowPage-1)+1)+"";
ResultSet resultSet=SqlHelper.executeSelect(sql, null);
//二次封装
try {
while(resultSet.next()){
User user=new User();
user.setId((int) resultSet.getObject("id"));
user.setUsername((String) resultSet.getObject("username"));
user.setPassword((String) resultSet.getObject("password"));
user.setEmail((String) resultSet.getObject("email"));
user.setLevel((String) resultSet.getObject("level"));
//对象放到集合里去
userArrayList.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return userArrayList;
}//获取总条数
public int getTotalPage(int perNumber){
int TotalPage=1;
String sql="select count(*) from user";
ResultSet resultSet=SqlHelper.executeSelect(sql, null);
try {
if(resultSet.next()){
int totalNumber=resultSet.getInt(1);
if(totalNumber%perNumber==0){
TotalPage= totalNumber/perNumber;
}else{
TotalPage= totalNumber/perNumber+1;
}
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return TotalPage;
}
}
E.如果可以使用forword()就不要使用sendRedirect()
4.5.4.5思路MVC的继续优化-删除功能
A.AdminUser
package admin;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pojo.User;
import service.UserService;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class AdminUser extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//js
resp.getWriter().println("<script type='text/javascript'>");
resp.getWriter().println("function goPage() {var nowPageTemp=document.getElementById('nowPage').value;"
+ "window.open('/wdfgdzx/AdminUser?nowPage='+nowPageTemp,'_self');}"
+ "function yes(){return confirm('确定要删除吗?')}");
resp.getWriter().println("</script>");
//resp.getWriter().println("");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
//定义分页需要的变量
int nowPage=1;
//接受传过来的nowPage,并且判断非空
if(req.getParameter("nowPage")!=null){
nowPage=Integer.parseInt(req.getParameter("nowPage"));//String转成int方法Integer.parseInt(str);
}
int perNumber=3;//每页展示多少
int totalPage=1;//计算出来的
try {
UserService userService=new UserService();
totalPage=userService.getTotalPage(perNumber);
ArrayList<User> userArrayList=userService.getUserByPage(nowPage, perNumber);
//查询数据库
resp.getWriter().println("<img src='Image/3.png'>"
+"欢迎您首长同志:"+req.getParameter("username")
+"<a href='/wdfgdzx/Admin'>返回主界面</a>"
+"&nbsp&nbsp&nbsp<a href='/wdfgdzx/Login'>安全退出</a>"
+ "<hr/>");
resp.getWriter().println("<table border='1' width='500px' cellspacing='0'>");
resp.getWriter().println("<tr><td>id</td><td>用户名</td><td>email</td><td>级别</td>"
+ "<td>删除用户</td><td>修改用户</td></tr>");
for(User user:userArrayList){
resp.getWriter().println("<tr><td>"+user.getId()+"</td>"
+ "<td>"+user.getUsername()+"</td>"
+ "<td>"+user.getEmail()+"</td>"
+ "<td>"+user.getLevel()+"</td>"
+ "<td><a href='/wdfgdzx/MyController?id="+user.getId()+"' οnclick='return yes();'>删除</a></td>"
+ "<td><a href='#'>修改</a></td></tr>");
}
resp.getWriter().println("<table>");
resp.getWriter().println("<br/>");
//显示分页
if(nowPage!=1){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+(nowPage-1)+"'>上一页</a>&nbsp");
}
for(int i=1;i<=totalPage;i++){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+i+"'><"+i+"></a>&nbsp");
}
if(nowPage!=totalPage){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+(nowPage+1)+"'>下一页</a>&nbsp");
}
//显示分页信息
resp.getWriter().println("&nbsp当前页"+nowPage+"/总页数"+totalPage);
resp.getWriter().println("<br/>");
resp.getWriter().println("跳转到第<input type='text' name='nowPage' id='nowPage'/>"
+ "<input type='button' value='GO' οnclick='goPage()'");
resp.getWriter().println("<br/>");
resp.getWriter().println("<hr/><img src='Image/4.png'>"); 
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
B.Controller
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pojo.User;
import service.UserService;
public class MyController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
String id=req.getParameter("id");
//调用UserService完成删除
if(new UserService().userDelete(id)){
//跳转到成功页面 能用forword就不用sendredirect。除非是跳转到非自己的页面
req.getRequestDispatcher("/TempPage").forward(req, resp);
}else{
req.getRequestDispatcher("/TempLose").forward(req, resp);
}
}
}
C.UserService
package service;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import pojo.User;
import util.SqlHelper;
public class UserService {
//验证用户是否合法的函数
public boolean checkUser(User user){
boolean flag=false;
//使用SqlHelper来执行任务
//获取必要参数
String sql="select *from user where username=? and password=?";
String parameters[]={user.getUsername(),user.getPassword()};
//执行工具类
ResultSet resultSet=SqlHelper.executeSelect(sql,parameters);
//判断
try {
if(resultSet.next()){
flag=true;
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return flag;
}//按照分页来获取用户
//公司把ResultSet—取成User对象—再把对象放到一个集合里面去ArrayList(集合)
public ArrayList getUserByPage(int nowPage,int perNumber){
ArrayList<User> userArrayList=new ArrayList<User>();
//查询语句
String sql="select *from user where id<="+perNumber*nowPage+" and id>="+(perNumber*(nowPage-1)+1)+"";
ResultSet resultSet=SqlHelper.executeSelect(sql, null);
//二次封装
try {
while(resultSet.next()){
User user=new User();
user.setId((int) resultSet.getObject("id"));
user.setUsername((String) resultSet.getObject("username"));
user.setPassword((String) resultSet.getObject("password"));
user.setEmail((String) resultSet.getObject("email"));
user.setLevel((String) resultSet.getObject("level"));
//对象放到集合里去
userArrayList.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return userArrayList;
}//获取总条数
public int getTotalPage(int perNumber){
int TotalPage=1;
String sql="select count(*) from user";
ResultSet resultSet=SqlHelper.executeSelect(sql, null);
try {
if(resultSet.next()){
int totalNumber=resultSet.getInt(1);
if(totalNumber%perNumber==0){
TotalPage= totalNumber/perNumber;
}else{
TotalPage= totalNumber/perNumber+1;
}
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return TotalPage;
}
//删除用户
public boolean userDelete(String id){
boolean flag=true;
String sql="delete from user where id=?";
String parameters[]={id};
try {
SqlHelper.executeUpdate(sql, parameters);
} catch (Exception e) {
flag=false;
}
return flag;
}
}
D.操作正常页
package view;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TempPage extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//返回一个界面
resp.getWriter().println("<img src='Image/3.png'><hr/>");
resp.getWriter().println("<h1>删除用户成功!!!</h1>");
resp.getWriter().println("<a href='/wdfgdzx/Admin'>返回主界面</a>");
resp.getWriter().println("<hr/><img src='Image/4.png'>");
}
}
E.操作失败页
package view;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TempLose extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//返回一个界面
resp.getWriter().println("<img src='Image/3.png'><hr/>");
resp.getWriter().println("<h1>对不起,删除失败!</h1>");
resp.getWriter().println("<a href='/wdfgdzx/Admin'>返回主界面</a>");
resp.getWriter().println("<hr/><img src='Image/4.png'>");
}
}
4.5.4.6思路MVC的继续优化-修改功能
A.点击去修改的界面-用户修改后再提交。发现还要去写个控制器,所以都把控制器写到MyController里去。所以要对操作打标签,标签就是
地址?type=delete/update等等。那么控制器是越少越好吗?不是,控制器的个数怎么定呢?同一类事务操作写在同一个控制器。不是就再写一个控制器就行了。
B.关于跳转到修改用户界面,有两种思路-一种是直接把参数带过去展示(但是增加网络开销,有空格还要处理乱码)-第二种是只传id然后再查
一把数据库把信息展示出来。推荐第二种
C.写程序的跳转带不带应用名称怎么判断?从用户发出的都要带,从服务器发出的都不要带。----//抽取后的方法 右击代码选择,Refactor-Extract method
D.报错停留:一个是sql语句写的时候不注意,写错sql语句-第二个是提交的参数名username/password等拼写错误,尽量复制
E.MyController
package controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pojo.User;
import service.UserService;
public class MyController extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//接受type
String type=req.getParameter("type");
UserService userService=new UserService();//创建对象从来等待使用
//调用UserService完成删除等操作
if(type.equals("delete")){
//接受id
String id=req.getParameter("id");
if(userService.userDelete(id)){
//跳转到成功页面 能用forword就不用sendredirect。除非是跳转到非自己的页面
req.setAttribute("say", "删除成功");
req.getRequestDispatcher("/TempPage").forward(req, resp);
}else{
req.setAttribute("say", "删除失败");
req.getRequestDispatcher("/TempLose").forward(req, resp);
}
}else if(type.equals("goUpdateView")){
//去修改界面
//通过id去查
String id=req.getParameter("id");
User user=userService.getUserById(id);
//为了让下一个servlet界面使用我们的user对象,我们可以把该对象传递下去放入到request域-对象中,要求同一个request
req.setAttribute("user", user);//同一个request这里决定必须用forword而不能用sendRedirect
req.getRequestDispatcher("/UserUpdate").forward(req, resp); 
}else if(type.equals("update")){
//接受用户新的信息,如果提交的数据格式不对,需要验证的
String id=req.getParameter("id");
String username=req.getParameter("username");
String password=req.getParameter("password");
String email=req.getParameter("email");
String level=req.getParameter("level");
//修改用户
User user=new User();
user.setId(Integer.parseInt(id));user.setEmail(email);
user.setUsername(username);user.setPassword(password);
user.setLevel(level);
//执行数据库操作
if(userService.userUpdate(user)){
req.setAttribute("say", "修改成功");
req.getRequestDispatcher("/TempPage").forward(req, resp);
}else{
req.setAttribute("say", "修改失败");
req.getRequestDispatcher("/TempLose").forward(req, resp);
}
}else if(type.equals("goAddView")){
//这里没有什么要处理的
req.getRequestDispatcher("/UserAdd").forward(req, resp);
}else if(type.equals("add")){
//抽取后的方法 右击代码选择,Refactor-Extract method
addFunction(req, resp, userService);
}
}
private void addFunction(HttpServletRequest req, HttpServletResponse resp,
UserService userService) throws ServletException, IOException {
//接受用户信息
String username=req.getParameter("username");
String password=req.getParameter("password");
String email=req.getParameter("email");
String level=req.getParameter("level");
//构建User
User user=new User();
user.setUsername(username);user.setPassword(password);
user.setLevel(level);user.setEmail(email);
if(userService.userAdd(user)){
req.setAttribute("say", "添加成功");
req.getRequestDispatcher("/TempPage").forward(req, resp);
}else{
req.setAttribute("say", "添加失败");
req.getRequestDispatcher("/TempLose").forward(req, resp);
}
}
}
F.UserService
package service;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
import pojo.User;
import util.SqlHelper;
public class UserService {
//验证用户是否合法的函数
public boolean checkUser(User user){
boolean flag=false;
//使用SqlHelper来执行任务
//获取必要参数
String sql="select *from user where username=? and password=?";
String parameters[]={user.getUsername(),user.getPassword()};
//执行工具类
ResultSet resultSet=SqlHelper.executeSelect(sql,parameters);
//判断
try {
if(resultSet.next()){
flag=true;
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return flag;
}//按照分页来获取用户
//公司把ResultSet—取成User对象—再把对象放到一个集合里面去ArrayList(集合)
public ArrayList getUserByPage(int nowPage,int perNumber){
ArrayList<User> userArrayList=new ArrayList<User>();
//查询语句
String sql="select *from user where id<="+perNumber*nowPage+" and id>="+(perNumber*(nowPage-1)+1)+"";
ResultSet resultSet=SqlHelper.executeSelect(sql, null);
//二次封装
try {
while(resultSet.next()){
User user=new User();
user.setId((int) resultSet.getObject("id"));
user.setUsername((String) resultSet.getObject("username"));
user.setPassword((String) resultSet.getObject("password"));
user.setEmail((String) resultSet.getObject("email"));
user.setLevel((String) resultSet.getObject("level"));
//对象放到集合里去
userArrayList.add(user);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return userArrayList;
}//获取总条数
public int getTotalPage(int perNumber){
int TotalPage=1;
String sql="select count(*) from user";
ResultSet resultSet=SqlHelper.executeSelect(sql, null);
try {
if(resultSet.next()){
int totalNumber=resultSet.getInt(1);
if(totalNumber%perNumber==0){
TotalPage= totalNumber/perNumber;
}else{
TotalPage= totalNumber/perNumber+1;
}
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return TotalPage;
}//删除用户
public boolean userDelete(String id){
boolean flag=true;
String sql="delete from user where id=?";
String parameters[]={id};
try {
SqlHelper.executeUpdate(sql, parameters);
} catch (Exception e) {
flag=false;
}
return flag;
}//通过id查询用户
public User getUserById(String id){
User user=new User();
String sql="select *from user where id=?";
String parameters[]={id};
ResultSet resultSet=SqlHelper.executeSelect(sql,parameters);
try {
if(resultSet.next()){
//二次封装
user.setId((int) resultSet.getObject("id"));
user.setUsername((String) resultSet.getObject("username"));
user.setPassword((String) resultSet.getObject("password"));
user.setEmail((String) resultSet.getObject("email"));
user.setLevel((String) resultSet.getObject("level"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//反向引用关闭资源
SqlHelper.close(SqlHelper.getConnection(), SqlHelper.getPreparedStatement(), resultSet);
}
return user;
}
//修改用户信息
public boolean userUpdate(User user){
boolean flag=true;
String sql="update user set username=?,email=?,level=?,password=? where id=?";
//需要把id转成字符串类型
String parameters[]={user.getUsername(),user.getEmail(),user.getLevel(),user.getPassword(),user.getId()+""};
try {
SqlHelper.executeUpdate(sql, parameters);
} catch (Exception e) {
flag=false;
}
return flag;
}
//添加用户信息
public boolean userAdd(User user){
boolean flag=true;
String sql="insert user(username,password,level,email) values(?,?,?,?)";
String parameters[]={user.getUsername(),user.getPassword(),user.getLevel(),user.getEmail()};
try {
SqlHelper.executeUpdate(sql, parameters);
} catch (Exception e) {
flag=false;
}
return flag;
}
}
G.管理页面
package admin;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Admin extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//resp.getWriter().println("Hi Company"+new java.util.Date());
resp.getWriter().println("<img src='Image/3.png'>"+"欢迎您首长同志:"+req.getParameter("username")
+"&nbsp&nbsp<a href='/wdfgdzx/Login'>返回登录界面</a>"+"<hr/>");
resp.getWriter().println("<h3>请选择操作</h3>");
resp.getWriter().println("<a href='/wdfgdzx/AdminUser'>管理用户</a><br/>");
resp.getWriter().println("<a href='/wdfgdzx/MyController?type=goAddView'>添加用户</a><br/>");
resp.getWriter().println("<a href='localhost/wdfgdzx/Login'>查找用户</a><br/>");
resp.getWriter().println("<a href='localhost/wdfgdzx/Login'>退出系统</a><br/>");
resp.getWriter().println("<hr/><img src='Image/4.png'>");
}
}
H.AdminUser
package admin;
import java.io.IOException;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pojo.User;
import service.UserService;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;
public class AdminUser extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//js
resp.getWriter().println("<script type='text/javascript'>");
resp.getWriter().println("function goPage() {var nowPageTemp=document.getElementById('nowPage').value;"
+ "window.open('/wdfgdzx/AdminUser?nowPage='+nowPageTemp,'_self');}"
+ "function yes(){return confirm('确定要删除吗?')}");
resp.getWriter().println("</script>");
//resp.getWriter().println("");
//到数据库验证用户名和密码servlet本身也是java类,因此其操作数据库和普通的java类是一样的
String username=req.getParameter("username");
String password=req.getParameter("password");
//定义分页需要的变量
int nowPage=1;
//接受传过来的nowPage,并且判断非空
if(req.getParameter("nowPage")!=null){
nowPage=Integer.parseInt(req.getParameter("nowPage"));//String转成int方法Integer.parseInt(str);
}
int perNumber=3;//每页展示多少
int totalPage=1;//计算出来的
try {
UserService userService=new UserService();
totalPage=userService.getTotalPage(perNumber);
ArrayList<User> userArrayList=userService.getUserByPage(nowPage, perNumber);
//查询数据库
resp.getWriter().println("<img src='Image/3.png'>"
+"欢迎您首长同志:"+req.getParameter("username")
+"<a href='/wdfgdzx/Admin'>返回主界面</a>"
+"&nbsp&nbsp&nbsp<a href='/wdfgdzx/Login'>安全退出</a>"
+ "<hr/>");
resp.getWriter().println("<table border='1' width='500px' cellspacing='0'>");
resp.getWriter().println("<tr><td>id</td><td>用户名</td><td>email</td><td>级别</td>"
+ "<td>删除用户</td><td>修改用户</td></tr>");
for(User user:userArrayList){
resp.getWriter().println("<tr><td>"+user.getId()+"</td>"
+ "<td>"+user.getUsername()+"</td>"
+ "<td>"+user.getEmail()+"</td>"
+ "<td>"+user.getLevel()+"</td>"
+ "<td><a href='/wdfgdzx/MyController?type=delete&id="+user.getId()+"' οnclick='return yes();'>删除</a></td>"
+ "<td><a href='/wdfgdzx/MyController?type=goUpdateView&id="+user.getId()+"'>修改</a></td></tr>");//也可以信息都带过去
}
resp.getWriter().println("<table>");
resp.getWriter().println("<br/>");
//显示分页
if(nowPage!=1){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+(nowPage-1)+"'>上一页</a>&nbsp");
}
for(int i=1;i<=totalPage;i++){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+i+"'><"+i+"></a>&nbsp");
}
if(nowPage!=totalPage){
resp.getWriter().println("<a href='/wdfgdzx/AdminUser?nowPage="+(nowPage+1)+"'>下一页</a>&nbsp");
}
//显示分页信息
resp.getWriter().println("&nbsp当前页"+nowPage+"/总页数"+totalPage);
resp.getWriter().println("<br/>");
resp.getWriter().println("跳转到第<input type='text' name='nowPage' id='nowPage'/>"
+ "<input type='button' value='GO' οnclick='goPage()'");
resp.getWriter().println("<br/>");
resp.getWriter().println("<hr/><img src='Image/4.png'>"); 
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
I.UserAdd
package view;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import pojo.User;
public class UserAdd extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// TODO Auto-generated method stub
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/html");
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
//展示出来
//展示出来
resp.getWriter().println("<img src='Image/3.png'>"
+"<a href='/wdfgdzx/Admin'>返回主界面</a>"
+"&nbsp&nbsp&nbsp<a href='/wdfgdzx/Login'>安全退出</a>"
+ "<hr/>");
resp.getWriter().println("<form action='/wdfgdzx/MyController?type=add' method='post'>");
resp.getWriter().println("<table border='1' width='300px' cellspacing='0'>");
//下个页面id自增,不让用户填写了
resp.getWriter().println("<tr><td>用户名</td><td><input type='text' name=username value=''/></td></tr>");
resp.getWriter().println("<tr><td>电子邮件</td><td><input type='text' name=email value='' /></td></tr>");
resp.getWriter().println("<tr><td>级别</td><td><input type='text' name=level value='' /></td></tr>");
resp.getWriter().println("<tr><td>密码</td><td><input type='text' name=password value='' /></td></tr>");
resp.getWriter().println("<tr><td><input type='submit' value='添加用户'/></td><td><input type='reset' value='重新填写'/></td></tr>");
resp.getWriter().println("<table>");
resp.getWriter().println("</form>");
resp.getWriter().println("<br/>");
resp.getWriter().println("<hr/><img src='Image/4.png'>"); 
}
}
J.压缩后代码记录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/834384.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CMakeLists.txt语法规则:数学运算 math

一. 简介 前面几篇文章学习了 CMakeLists.txt语法中的一些常用变量&#xff0c;常用命令&#xff0c;双引号的作用。条件判断语句&#xff0c;循环语句等等。 本文简单学习一下 CMakeLists.txt语法中数学运算 match。 二. CMakeLists.txt语法规则&#xff1a;数学运算 math 在…

MySQL数据库实验三

本文承接前面的俩次实验基础上完成&#xff0c;不过实现的都是基础操作的练习 目录 目录 前言 实验目的 实验要求 实验内容及步骤 updata操作 delete操作 alter操作 添加列 删除列 修改列的数据类型 要求实现 实验结果 代码结果 注意事项 思考题 总结 前言 本文是MySQL数据库…

身份证OCR识别接口如何对接

身份证OCR识别接口又叫身份证识别API接口、身份证正反面文字识别接口&#xff0c;指的是传入身份证照片&#xff0c;精准识别静态身份证图像上的文字信息&#xff0c;如果传的是正面照片只返回正面信息&#xff0c;如果传的是反面只返回反面信息。那么身份证OCR识别接口如何对接…

软件接口测试规范流程

1、需求分析 1.1 确认测试目的和测试对象&#xff1a; 了解需求并明确测试目的&#xff0c;如测试一个本地 API 还是跨网站的远程 API。 1.2 确认测试的基本条件: 确定测试所需的测试数据&#xff0c;测试环境以及测试团队中的角色和职责。 1.3. 对接口文档进行验证&#xf…

Windows系统使用powershell批量移动特定起始位置的“快捷方式”

移动特定起始位置的“快捷方式” 快捷方式都对应一个的目标和“起始位置”&#xff0c;现在想要把特定起始位置的快捷方式移动到一个文件夹中。 新建文本文档&#xff0c;输入如下内容&#xff1a; # 设置变量 $oldPath "D:\111\111_1" $newPath "D:\111\1…

AI-数学-高中55-随机变量正态分布

原作者视频&#xff1a;【随机变量】【一数辞典】6正态分布_哔哩哔哩_bilibili 整个概率面积 S 1。 示例&#xff1a; 对称轴平均分μ90分&#xff0c;西格玛&#xff08;确定最高点的值&#xff0c;值越大越缓&#xff0c;越小分布曲线峰值越瘦高&#xff09;σ20分。

【前端热门框架【vue框架】】——事件处理与表单输入绑定以及学习技巧,让学习如此简单

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;程序员-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

游戏专用设备指纹方案解析

如同人类拥有独一无二的指纹&#xff0c;设备也有设备的指纹&#xff0c;我们可以把设备指纹理解为设备的唯一识别码。 构建设备指纹需要采集设备硬件信息、软件信息、环境信息、网络信息等维度信息&#xff0c;进行加密/压缩&#xff0c;再通过算法处理&#xff0c;赋予设备唯…

音转文工具,9.8k star! 【送源码】

我们经常会遇到将音频转为文字的情况&#xff0c;比如在开会时录音的会议纪要、上课时录下的老师讲课内容。虽然网上也有一些在线的工具可以将音频转为文字&#xff0c;但是考虑到数据安全和费用问题&#xff0c;使用起来也不是很方便。 今天了不起给大家介绍一款开源工具——…

短信清空了!华为手机短信删除了怎么恢复?

“有没有人知道这是怎么回事呀&#xff0c;原先有一千多条未读一直放着没管&#xff0c;昨天根本没打开短信这个软件&#xff0c;今晚突然发现只剩一条了&#xff0c;是华为手机自动清理了吗&#xff01;到底该怎么恢复呀&#xff1f;我真崩溃&#xff01;” 在日常生活中&…

设计模式之服务定位器模式

想象一下&#xff0c;你的Java应用是一座庞大的迷宫&#xff0c;里面藏着无数宝贵的服务宝藏&#xff0c;而你正需要一张精确的藏宝图来指引方向&#xff0c;迅速找到并利用这些宝藏。服务定位器模式&#xff0c;正是这样一张神奇的地图&#xff0c;它帮你动态定位并获取应用中…

振动分析的一些概念

一.时域分析 振动测试领域中&#xff0c;通常使用标准是ISO 10816系列标准&#xff0c;其要去使用有效值&#xff08;RMS&#xff09;来表示震动信号的能量大小&#xff0c;并提供一组限制值&#xff0c;以帮助用户评估机器的振动水平是否正常。 1.位移&#xff1a; 峰峰&…

【C++】C/C++中新const用法:const成员

欢迎来到CILMY23的博客 本篇主题为&#xff1a; C/C中新const用法&#xff1a;const成员 个人主页&#xff1a;CILMY23-CSDN博客 系列专栏&#xff1a;Python | C | C语言 | 数据结构与算法 | 贪心算法 | Linux 感谢观看&#xff0c;支持的可以给个一键三连&#xff0c;点赞…

8、基本数据类型转换(自动转换和强制转换)

基本类型转换 1、自动类型转换2、强制类型转换 1、自动类型转换 定义&#xff1a;当Java程序在进行赋值或者运算时&#xff0c;精度小的类型会自动转换成精度大的数据类型&#xff0c;这个就是自动类型转换。&#xff08;自动小转大&#xff09; 背多芬&#xff1a; 这里要明…

【二维数组】

目录 作业 对比&#xff1a; 结果&#xff1a; 二维数组 二维数组的初始化 作业 作业 #define max(a,b)(a>b)?a:b #include<stdio.h> int main() {int x, y,c;scanf("%d %d", &x,&y);cmax(x, y);printf("%d", c);return 0; } 对比…

深入理解Django:中间件与信号处理的艺术

title: 深入理解Django&#xff1a;中间件与信号处理的艺术 date: 2024/5/9 18:41:21 updated: 2024/5/9 18:41:21 categories: 后端开发 tags: Django中间件信号异步性能缓存多语言 引言 在当今的Web开发领域&#xff0c;Django以其强大的功能、简洁的代码结构和高度的可扩…

小丑的身份证和复印件 (BFS + Floyd)

本题链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 题目&#xff1a; 样例&#xff1a; 输入 2 10 (JOKERjoke #####asdr) 输出 12 思路&#xff1a; 根据题意&#xff0c;要求最短时间&#xff0c;实际上也可以理解为最短距离。 所以应该联想到有关最短距离的算法&…

开源项目介绍-02 Aubio【1】环境配置和使用 @ Ubuntu + Pycharm + Python

前言&#xff1a; aubio 是一组算法和工具&#xff0c;用于标记和变换音乐和声音。它扫描或监听音频信号&#xff0c;并尝试识别音乐事件。例如&#xff0c;当鼓被击打时&#xff0c;它能检测到音符的频率&#xff0c;或者一个有节奏的旋律的节拍是多少。 aubio 的功能包括&a…

基于stm32的spi从机实验HAL库编程

目录 基于stm32的spi从机实验HAL库编程前言业务场景硬件设计接线配置swd接口配置spi配置DMA配置中断配置系统时钟配置工程生成代码写点从机代码上机现象后记本文使用的测试工程 基于stm32的spi从机实验HAL库编程 前言 在微控制器的世界中&#xff0c;串行外设接口(SPI)是一种…