├── LearningServlet.iml ├── README.md ├── myservlet01 ├── pom.xml └── src │ └── main │ ├── java │ ├── AppTest.java │ └── com │ │ └── ray │ │ ├── servlet │ │ ├── App.java │ │ └── myservlet │ │ │ └── MyServlet.java │ │ └── socket │ │ └── App.java │ └── webapp │ ├── WEB-INF │ └── web.xml │ └── index.jsp ├── myservlet02 ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── ray │ │ └── MyServlet.java │ └── webapp │ ├── WEB-INF │ └── web.xml │ └── index.jsp ├── myservlet03 ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── ray │ │ └── MyServlet.java │ └── webapp │ ├── WEB-INF │ └── web.xml │ └── index.jsp ├── myservlet04 ├── README.md ├── pom.xml └── src │ ├── banana.png │ └── main │ ├── java │ └── com │ │ └── ray │ │ └── MyServlet.java │ └── webapp │ ├── WEB-INF │ └── web.xml │ └── index.jsp ├── myservlet05 ├── README.md ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── ray │ │ └── MyServlet.java │ └── webapp │ ├── WEB-INF │ └── web.xml │ ├── index.jsp │ └── spring-mvc官方手册.pdf ├── myservlet06 ├── myservlet06.iml ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── ray │ │ │ ├── entity │ │ │ └── User.java │ │ │ ├── servlet │ │ │ └── UserServlet.java │ │ │ └── utils │ │ │ ├── DbConfig.java │ │ │ └── DbUtils.java │ ├── resources │ │ └── db.properties │ └── webapp │ │ ├── WEB-INF │ │ └── web.xml │ │ └── index.jsp │ └── test │ └── DbTest.java └── pom.xml /LearningServlet.iml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | * [项目记录](#项目记录) 2 | * [HTTP协议相关](#http协议相关) 3 | * [HTTP协议的特征](#http协议的特征) 4 | * [请求类型](#请求类型) 5 | * [GET和POST的区别](#get和post的区别) 6 | * [HTTP数据包](#http数据包) 7 | * [GET方式提交(Java代码控制台打印为例)](#get方式提交java代码控制台打印为例) 8 | * [Servlet继承结构](#servlet继承结构) 9 | * [Servlet的生命周期](#servlet的生命周期) 10 | * [Tomcat执行Servlet过程(伪代码)](#tomcat执行servlet过程伪代码) 11 | * [Servlet的作用](#servlet的作用) 12 | * [Servlet如何获取表单数据](#servlet如何获取表单数据) 13 | * [解决Servlet中的中文乱码问题](#解决servlet中的中文乱码问题) 14 | * [关于Servlet的线程安全的问题](#关于servlet的线程安全的问题) 15 | * [Servlet文件上传](#servlet文件上传) 16 | * [自启动的Servlet](#自启动的servlet) 17 | * [Servlet的常见对象](#servlet的常见对象) 18 | * [ServletContext](#servletcontext) 19 | * [ServletContext的主要用法](#servletcontext的主要用法) 20 | * [ServletConfig](#servletconfig) 21 | * [Cookie](#cookie) 22 | * [什么是Cookie](#什么是cookie) 23 | * [Cookie中如何传递中文信息](#cookie中如何传递中文信息) 24 | * [HttpSession](#httpsession) 25 | * [什么是HttpSession](#什么是httpsession) 26 | * [HttpSession的运行过程](#httpsession的运行过程) 27 | * [HttpSession的生命周期](#httpsession的生命周期) 28 | * [编写一个自定义Servlet](#编写一个自定义servlet) 29 | * [自定义Servlet类继承HttPServlet,并且重写doGet和doPost方法](#自定义servlet类继承httpservlet并且重写doget和dopost方法) 30 | * [编写到运行Servlet的步骤(不适用IDE的方法)](#编写到运行servlet的步骤不适用ide的方法) 31 | ## 项目记录 32 | + myServlet01: 实现简单的Servlet的Hello World 33 | + myServlet02: 实现三种乱码处理方案 34 | + myServlet03: 实现通过Servlet的API获取用户浏览器的基本信息 35 | + myServlet04: 实现通过IO流向客户端传输图片并展示 36 | + myServlet05: 实现文件下载 37 | + myServlet06: 实现通过JDBC对数据库进行操作,待施工 38 | 39 | 本笔记为个人学习思考解惑记录,多方面引用互联网资料。 40 | 若有纰漏,欢迎指正。 41 | 42 | ## HTTP协议相关 43 | ### HTTP协议的特征 44 | 45 | 1. 单向性:客户端和服务端建立连接依靠于客户端发送请求,如果客户端不发送请求,服务端不会主动发送数据到客户端 46 | 2. 无状态:HTTP对于事务处理没有记忆能力。无法“断点续传” 47 | 3. 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型有Content-Type加以标记 48 | 4. 简单快速:客户端向服务器发送请求时,只需传送请求方法和路径。请求方法常用的有GET,POST,HEAD,PUT,DELETE。每种方法规定了客户端与服务器建立连接的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度快 49 | 50 | ------------ 51 | 52 | 53 | ### 请求类型 54 | #### GET和POST的区别 55 | 56 | 1. GET方式提交表单时,表单数据会在地址栏显示。而POST不会 57 | 2. GET方式提交表单时,表单数据长度是有限的(地址栏长度有限)。而POST理论上没有限制 58 | 3. GET方式提交表单时,表单数据都是以字符方式提交。而POST既可以用字符也可以用字节,默认用字符。 59 | 4. GET方式提交表单会在Http数据包中的第一行出现,而POST提交表单会在空一行的body中出现 60 | 5. GET请求能够被缓存,POST请求不能被缓存下来 61 | 62 | ------------ 63 | 64 | 65 | ### HTTP数据包 66 | #### GET方式提交(Java代码控制台打印为例) 67 | 68 | ```java 69 | public class App { 70 | public static void main(String[] args) { 71 | try { 72 | ServerSocket ss = new ServerSocket(8080); 73 | Socket s = ss.accept(); 74 | BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); 75 | String str; 76 | while ((str = br.readLine()) != null){ 77 | System.out.println(str); 78 | } 79 | } catch (IOException e) { 80 | e.printStackTrace(); 81 | } 82 | } 83 | } 84 | ``` 85 | 运行以上代码后,在浏览器输入localhost:8080 86 | 则在控制台打印以下内容 87 | ```text 88 | GET / HTTP/1.1 89 | Host: localhost:8080 90 | Connection: keep-alive 91 | Upgrade-Insecure-Requests: 1 92 | User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 93 | Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 94 | Accept-Encoding: gzip, deflate, br 95 | Accept-Language: zh-CN,zh;q=0.9 96 | Cookie: Idea-7798877d=aa86ef31-e4df-4cc6-bf8d-66407314771c 97 | ``` 98 | 99 | ------------ 100 | 101 | 102 | ## Servlet继承结构 103 | 104 | ![image](https://www.crzmy.com/wp-content/uploads/2018/07/Servlet.png) 105 | 106 | ------------ 107 | 108 | 109 | ## Servlet的生命周期 110 | 111 | Servlet接口中定义了作为一个Servlet在整个生命周期中应该拥有三个阶段 112 | 1. 初始化 113 | 2. 服务 service 114 | 3. 销毁 destroy 115 | 116 | ```text 117 | Servlet的生命周期是由容器管理的,Servlet初始化以后立即调用init()方法,开发者可以重写该方法让Servlet初始化以后执行相应的操作 118 | ``` 119 | 120 | ------------ 121 | 122 | 123 | ### Tomcat执行Servlet过程(伪代码) 124 | 125 | 当客户端请求Servlet的时,Tomcat获取HTTP数据包信息,得到了头部信息中的 126 | ```text 127 | GET /myservlet/hello.do HTTP/1.1 128 | ``` 129 | 假如有一个类存储HTTP相关信息 130 | ```java 131 | public class HttpInfo{ 132 | private String method; 133 | private String uri; 134 | private String protocol; 135 | .... 136 | /* getter and setter */ 137 | } 138 | ``` 139 | ```java 140 | // Tomcat新建一个ServerSocket对象,监听端口 141 | ServerSocket socket = new ServerSocket(监听端口号); 142 | Socket s; 143 | boolean flag = true; 144 | while(flag){ 145 | // 获取对应客户端的Socket对象 146 | s = socket.accept(); 147 | } 148 | // 通过IO流去读取数据 149 | BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream(),"iso-8859-1"); 150 | String line; 151 | HttpInfo info = new HttpInfo(); 152 | HttpServletRequest request; 153 | HttpServletResponse response; 154 | while((line = br.readLine()) != null){ 155 | // Tomcat解析HTTP数据包 156 | // 例:拆分头部第一行的信息,获取请求方法,URI,协议版本 157 | String[] arr = line.split("\\s"); 158 | info.setMethod(arr[0]); 159 | // 存储的已经处理字符串后得到的uri 160 | info.setUri(arr[1]); 161 | info.setProtocol(arr[2]); 162 | // 处理第一行以外的其他信息 163 | ... 164 | request = new HttpServetRequest(); 165 | request.setMethod(arr[0]); 166 | // 例如获取表单数据 167 | ... 168 | 169 | // Tomcat解析客户端的相关信息,比如发送请求的客户端的IP地址 170 | response.setSocket(s); 171 | } 172 | 173 | // 对请求的HTTP数据包解析完毕后,处理请求 174 | // Tomcat在启动时就会解析项目下的部署描述文件web.xml 175 | // 在里面我们在标签里配置了我们Servlet类的全路径,通过反射获取到Class对象,进而通过Class.newInstance()方法生成实例化对象. 176 | Class clazz = Class.forName(配置文件中Servlet类的全路径); 177 | // 多态性,父类引用指向子类对象 178 | Servlet obj = clazz.newInstance(); 179 | // Servlet对象初始化之后的相关操作 180 | // 比如,人到了公司打卡后,职工对象就初始化好了,但是你还不能直接去工作(service) 181 | // 还要去找到你的办公位置,还要把电脑开机等操作,这就是init()里应该做的事情 182 | // 调用的是重写后的init()方法 183 | obj.init(); 184 | // 说明是多线程的,只是例子,这种方法开启线程很蠢 185 | new Thread(new St(request, response)).start(); 186 | ... 187 | ... 188 | // 到了容器要销毁Servlet对象之前 189 | // 容器就会去调用destroy()方法 190 | // 还是那个上班的例子 191 | // 办公楼晚上要锁门了,要把所有人都赶走,但是职工必须得在赶走之前,把文档,代码这些保存好,然后把电脑关机,关掉办公室的灯等动作 192 | // 这就是destroy()方法做的类似事情 193 | ``` 194 | 模拟Tomcat里多线程 195 | ```java 196 | public St implements Runnable{ 197 | private Servlet obj; 198 | private HttpServletRequest request; 199 | private HttpServletResponse response; 200 | 201 | public St(Servlet obj, HttpServletRequest request, HttpServletResponse response){ 202 | this.obj = obj; 203 | this.request = request; 204 | this.response = response; 205 | } 206 | @Override 207 | public void run(){ 208 | // 执行HttpServlet里的service()方法 209 | this.obj.service(request, response); 210 | // 执行后续操作 211 | // 判断request里保存的请求方式 212 | // GET POST ... 213 | // 根据不同的方式请求不同的方法,以GET为例 214 | // 会去调用重写后的doGet方法 215 | ... 216 | } 217 | } 218 | ``` 219 | > 总结: 220 | 221 | Servlet的生命周期是由容器管理的,分为init,service和destroy三个阶段. 222 | 当有客户端第一次访问这个Servlet时,容器会立即初始化这个Servlet对象,初始化结束以后立即调用init()方法,并且在新的线程中调用service()方法. 223 | 容器会将初始化后的Servlet对象进行缓存,当有客户端再次请求该Servlet时,容器不会再进行创建,而是直接在新的线程里调用service()方法. 224 | 当容器关闭时,容器会在销毁这个Servlet对象之前,调用一次destroy()方法. 225 | 226 | ------------ 227 | 228 | 229 | ## Servlet的作用 230 | 231 | 1. 获取表单数据 232 | 2. 获取浏览器的附加信息 233 | 3. 处理数据(本身不具备处理数据的能力,比如持久化.它是通过调用其他的处理数据的方式来实现的,比如JDBC...) 234 | 4. 给客户端产生一个响应 235 | 5. 在响应中添加附加信息 236 | 237 | ------------ 238 | 239 | 240 | ### Servlet如何获取表单数据 241 | 242 | 在HttpServletRequest里有几个方法. 243 | ```java 244 | 1. String getParameter(String name) 245 | 这个方法处理键值对比如key=value,通过key来获取对应的value.但是这个方法不能获取页面上checkbox的value,因为他的数据格式是key=value1&key=value2&key=value3 246 | 2. String[] getParameterValues(String name) 247 | 该方法就可以处理checkbox的value,它可以获取对应key的所有value 248 | 3. String getQueryingString(String str) 249 | 这个方法可以获取URL中的查询字符串(?后面的字符串) 250 | 4. Map getParameterMap() 251 | 这个方法可以获取请求参数将其封装成Map数据格式 252 | ``` 253 | 254 | ------------ 255 | 256 | 257 | ### 解决Servlet中的中文乱码问题 258 | 259 | 首先要知道的是Tomcat的默认字符集是ISO-8859-1 260 | 1. 通用,通过jdk的new String产生新的对应编码的String对象 261 | 262 | ```java 263 | /*解决中文乱码问题 第一种方式 264 | GET和POST都有效,但不推荐,会有大量冗余代码*/ 265 | 266 | String name = request.getParameter("name"); 267 | // 乱码 268 | System.out.println(name); 269 | name = new String(name.getBytes("iso-8859-1"),"utf-8"); 270 | // 正常 271 | System.out.println(name); 272 | ``` 273 | 2. 只适用POST,通过HttpServletRequest的API 274 | 275 | ```java 276 | /*解决中文乱码问题 第二种方式 277 | 只适用于POST请求,使用request里的内置方法*/ 278 | 279 | request.setCharacterEncoding("utf-8"); 280 | String name = request.getParameter("name"); 281 | // 正常 282 | System.out.println(name); 283 | ``` 284 | 3. 通用,修改Tomcat配置文件server.xml 285 | 286 | ```xml 287 | 291 | ``` 292 | ```java 293 | /*解决中文乱码问题 第三种方式 294 | * 修改Tomcat配置文件server.xml 295 | * 在Connector节点添加URIEncoding="utf-8" 296 | * */ 297 | String value = request.getParameter("name"); 298 | // 正常 299 | System.out.println(value); 300 | ``` 301 | 302 | ------------ 303 | 304 | 305 | ### 关于Servlet的线程安全的问题 306 | 307 | Servlet是一个线程不安全的技术,在Servlet中定义成员变量时,如果一定要定义成员变量,那么以读取为主.尽量不要同时读同时写.如果一定有这样的需求,则需要加锁. 308 | ~~interface SingeThreadModel~~ 是Servlet提供的一个标识接口,该接口标识实现了该接口的Servlet的运行方式会由并行化改为串行化.效率低下,所以该接口在解决线程安全的问题时,已经不推荐使用了. 309 | 310 | ------------ 311 | 312 | ### Servlet文件上传 313 | 314 | 1. 在实现文件上传是,表单的提交方式必须是POST方式提交,因为POST请求才支持让表单数据以字节的方式提交,而GET只能是字符提交. 315 | 2. 在form表单中修改请求的信息,将原来默认的字符提交修改为字节提交:通过修改form标签中的enctype属性,将其值改为multipart/form-data,该属性表示当前表单为字节格式,当服务器接收到当前数据包的时候,则不会去解析,所以也无法使用request.getParameter()去获取表单数据. 316 | 3. 在2的情况下,如果需要处理表单中的内容,需要通过request对象的getInputStream()方法来获取一个通信流,通过对流对象的操作完成相应的表单处理.但是相比更推荐使用Apache的common-fileupload组件. 317 | 318 | ------------ 319 | 320 | 321 | ### 自启动的Servlet 322 | 自启动的Servlet的实例化不依赖于客户端请求,而是依赖于容器.当容器启动时就回去初始化这个Servlet. 323 | 在web.xml文件中在对应Servlet的节点最后一行添加 324 | ```xml 325 | 1 326 | ``` 327 | 其中数字表示启动优先级,数字越小,优先级越高 328 | 329 | ------------ 330 | 331 | ### Servlet的常见对象 332 | #### ServletContext 333 | ##### ServletContext的主要用法 334 | 1. 相对路径转绝对路径 335 | ```java 336 | ServletContext sc = this.getServletContext(); 337 | String rootPath = sc.getRealPath("/file.txt"); 338 | File file = new File(rootPath); 339 | ``` 340 | 2. 获取容器附加信息 341 | ```java 342 | // 获取Servlet的主版本号 343 | int getMajorVersion(); 344 | // 获取Servlet的副版本号 345 | int getMinorVersion(); 346 | // 获取服务器的版本信息 347 | String getServerInfo(); 348 | ... 349 | ... 350 | ``` 351 | 3. 全局容器 352 | Servlet通过以下两个API完成对自身的添加和读取数据的操作. 353 | ```java 354 | // 添加数据 355 | void setAttribute(String name, Object value); 356 | // 获取数据 357 | Object getAttribute(String name); 358 | ``` 359 | 注意: 360 | 建议不要存储业务数据,数据会随着生命周期一直在内存中,增大了服务器的负担.其次也避免了与数据库数据同步的问题. 361 | 362 | 4. 读取web.xml里的配置信息 363 | ```xml 364 | 365 | key 366 | value 367 | 368 | ``` 369 | 通过以下方式可以获取该节点信息 370 | ```java 371 | ServletContext sc = this.getServletContext(); 372 | String value = sc.getInitParameter("key"); 373 | ``` 374 | 该配置信息是全局可访问,可以配置多个,但是在一个里只能有一个key/value配置. 375 | #### ServletConfig 376 | 作用:用于读取在web.xml的节点中的配置信息.在节点中可以加入节点. 377 | 378 | ```xml 379 | 380 | MyServlet 381 | com.ray.MyServlet 382 | 383 | key 384 | value 385 | 386 | 387 | ``` 388 | 通过以下方式可以获取配置的key/value 389 | ```java 390 | // 手动写key获得value 391 | ServletConfig config = this.getServletConfig(); 392 | String value = sc.getInitParameter("key") 393 | 394 | // 可以使用另一个方法来获得所有的key/value 395 | ServletConfig config = this.getServletConfig(); 396 | Enumeration parameterNames = sc.getInitParameterNames(); 397 | String value = ""; 398 | while (parameterNames.hasMoreElements()){ 399 | value = sc.getInitParameter(parameterNames.nextElement()); 400 | System.out.println(value); 401 | } 402 | ``` 403 | 同样在一个节点中可以配置多个,但是一个只能配置一个key/value信息. 404 | 但是这个配置信息是只能在对应配置的Servlet才能访问到.其他Servlet无法访问. 405 | #### Cookie 406 | ##### 什么是Cookie 407 | Cookie是一个依赖于客户端维持会话状态的对象 408 | Cookie的特点:如果程序需要给客户端浏览器返回一个Cookie,那么则需要自己来创建;Cookie的结构为key/value结构. 409 | Cookie分为两种: 410 | 1. 状态Cookie: 随着浏览器的生命周期存在,浏览器关闭,则对象消失 411 | 2. 持久化Cookie: Cookie对象持久化到磁盘中,当Cookie的存活时间到达时,浏览器不会再在请求中传递该Cookie.对于这些Cookie文件,浏览器会自己管理.通过setMaxAge(int s)方法来将Cookie持久化. 412 | 413 | 当需要使用Cookie对象向客户端浏览器传递数据,数据本身不能是中文. 414 | 当客户端浏览器请求Servlet是,客户端浏览器会将该服务器以前写回的所有Cookie对象在请求中传递. 415 | 416 | 可以通过以下简单的实例来实现判断用户访问 417 | ```java 418 | @Override 419 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 420 | request.setContentType("text/html;charset=utf-8"); 421 | PrintWriter pw = response.getPrintWriter(); 422 | Cookie[] cookies = request.getCookies(); 423 | if(cookies == null || cookies.length <= 0){ 424 | pw.println("欢迎光临!"); 425 | Cookie c = new Cookie("cookie","cookie"); 426 | // 持久化Cookie,如果没有这一句则是状态Cookie 427 | c.setMaxAge(120); 428 | response.addCookie(c); 429 | } else { 430 | pw.println("欢迎回来!"); 431 | } 432 | } 433 | 434 | @Override 435 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 436 | this.doPost(request, response); 437 | } 438 | ``` 439 | 440 | ##### Cookie中如何传递中文信息 441 | 1. 通过可逆的加密算法 442 | ```java 443 | /* 使用一个Java的加密字符串工具包 EncryptUtils,自行百度或编写 */ 444 | .... 445 | Cookie[] cookies = request.getCookies(); 446 | if(cookies == null || cookies.length<=0){ 447 | String str = "今天是二零一八年七月十二日"; 448 | // 加密字符串 449 | String ciphertext = EncryptUtils.encrypt(str); 450 | Cookie c = new Cookie("cookie", ciphertext); 451 | c.setMaxAge(60*60*24); 452 | response.addCookie(c); 453 | } else { 454 | pw.println("欢迎回来!"); 455 | Cookie c = null; 456 | for(Cookie cookie : cookies){ 457 | if("cookie".equals(cookie.getName())){ 458 | c = cookie; 459 | break; 460 | } 461 | } 462 | if(c != null){ 463 | // 解密字符串 464 | String text = EncryptUtils.decrypt(c.getValue()); 465 | pw.println("欢迎回来!" + text); 466 | } 467 | } 468 | ``` 469 | 2. 通过字符编码 470 | ```java 471 | /* 472 | 使用了java.net包下的操作URL编码的包 473 | 修改了上面代码的加密解密两行,其他完全一致 */ 474 | .... 475 | Cookie[] cookies = request.getCookies(); 476 | if(cookies == null || cookies.length<=0){ 477 | String str = "今天是二零一八年七月十二日"; 478 | // 加密字符串 479 | String ciphertext = URLEndoder.encode(str, "utf-8"); 480 | Cookie c = new Cookie("cookie", ciphertext); 481 | // 单位是秒,60 * 60 * 24 = 1天 482 | c.setMaxAge(60*60*24); 483 | response.addCookie(c); 484 | } else { 485 | pw.println("欢迎回来!"); 486 | Cookie c = null; 487 | for(Cookie cookie : cookies){ 488 | if("cookie".equals(cookie.getName())){ 489 | c = cookie; 490 | break; 491 | } 492 | } 493 | if(c != null){ 494 | // 解密字符串 495 | String text = URLDecoder.decode(c.getValue(), "utf-8"); 496 | pw.println("欢迎回来!" + text); 497 | } 498 | } 499 | ``` 500 | 501 | ------------ 502 | 503 | 504 | #### HttpSession 505 | ##### 什么是HttpSession 506 | HttpSession对象可以建立客户端与服务器之间的对话,但会话是否建立.取决于服务器是否为这个客户端创建了HttpSession对象.如果是,则HttpSession就表示当前客户端与服务器的会话已经建立.进而该HttpSession对象只为该客户端使用,不会与其他客户端共享. 507 | 508 | ##### HttpSession的运行过程 509 | 首先HttpServletRequest中有两个获取HttpSession的方法,源码如下,删除了部的注释 510 | 511 | ```java 512 | /** 513 | * 514 | * Returns the current HttpSession associated with 515 | * this request or, if there is no 516 | * current session and create is true, returns 517 | * a new session. 518 | * 519 | * If create is false 520 | * and the request has no valid HttpSession, 521 | * this method returns null. 522 | * 523 | * @param create true to create a new session for 524 | * this request if necessary; 525 | * false to return null if there's no current session 526 | * 527 | * @return the HttpSession associated with this request or null 528 | * if create is false and the request has no valid session 529 | * 530 | */ 531 | 532 | public HttpSession getSession(boolean create); 533 | 534 | /** 535 | * 536 | * Returns the current session associated with this request, 537 | * or if the request does not have a session, creates one. 538 | * 539 | * @return the HttpSession associated with this request 540 | */ 541 | public HttpSession getSession(); 542 | ``` 543 | 阅读了上面的代码可以知道,getSession()和getSession(true)是同一个执行结果. 544 | 当客户端浏览器访问Servlet时,如果代码中调用了getSession(boolean create)或者getSession(),那么服务器会根据传递的参数来执行不同的逻辑.如果create参数是true或者没有参数则会在底层的SessionId/HttpSession对象映射中寻找是否有该客户端的HttpSession对象,如果没有则创建一个新的HttpSession对象并且把该对象的SessionId通过状态Cookie返回给客户端.如果create参数是false,同样也会在底层的SessionId/HttpSession对象映射中寻找是否有该客户端的HttpSession对象,但是如果没有对应的HttpSession对象,则会返回null. 545 | 546 | ------------ 547 | 548 | 549 | ##### HttpSession的生命周期 550 | 551 | 1. 创建: 当有客户端浏览器第一次请求Servlet时,该Servlet中调用了HttpServletRequest里的getSession(boolean create)或者request.getSession()方法时,则会创建一个HttpSession对象. 552 | 2. 销毁: 553 | 1. 使用HttpSession里的invalidate()方法,该方法会直接是该Session直接销毁,并且取消绑定的任何对象. 554 | ```java 555 | /** 556 | * 557 | * Invalidates this session then unbinds any objects bound 558 | * to it. 559 | * 560 | * @exception IllegalStateException if this method is called on an 561 | * already invalidated session 562 | * 563 | */ 564 | 565 | public void invalidate(); 566 | ``` 567 | 2. 修改Tomcat里的conf目录下的web.xml文件,默认是30分钟,超过配置时间则会销毁,对Tomcat里所有项目有效 568 | ```xml 569 | 570 | 30 571 | 572 | ``` 573 | 3. 修改本项目的web.xml,同理也是超过配置时间则会自动销毁,但是仅对本项目有效. 574 | ```xml 575 | 576 | 1 577 | 578 | ``` 579 | 580 | ------------ 581 | 582 | 583 | ## 编写一个自定义Servlet 584 | 585 | ### 自定义Servlet类继承HttPServlet,并且重写doGet和doPost方法 586 | 587 | ```java 588 | public class MyServlet extends HttpServlet { 589 | 590 | public MyServlet() { 591 | super(); 592 | } 593 | 594 | @Override 595 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 596 | PrintWriter pw = response.getWriter(); 597 | pw.println( 598 | "HelloWorld" + 599 | "HelloWorld"+ 600 | ""); 601 | pw.close(); 602 | } 603 | 604 | @Override 605 | public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 606 | 607 | } 608 | } 609 | 610 | ``` 611 | ### 编写到运行Servlet的步骤(不适用IDE的方法) 612 | 613 | 1. 编写自定义Servlet类继承HttpServlet 614 | 2. 重写doGet和doPost方法 615 | 3. 使用javac工具编译代码 616 | 4. 在Tomcat的webapp目录下创建项目名称文件夹,在该文件夹下创建WEB-INF目录,继续在WEB-INF下创建classes目录,在里面创建包结构 617 | 5. 把javac生成的.class文件放入对应的包结构目录下 618 | 6. 在WEB-INF目录下创建web.xml 619 | 7. 编辑web.xml,配置Servlet 620 | ```xml 621 | 622 | ArchetypeCreatedWebApplication 623 | 624 | 625 | myServlet 626 | com.ray.servlet.myservlet.MyServlet 627 | 628 | 629 | 630 | myServlet 631 | *.do 632 | 633 | 634 | ``` 635 | 8. 启动Tomcat容器 636 | 9. 在浏览器地址栏输入 637 | ```text 638 | localhost:8080/(servlet名字)/(请求路径) 639 | 本例为:localhost:8080/myServlet/hello.do 640 | ``` 641 | 10. 结果展示 642 | ![image](https://note.youdao.com/yws/api/personal/file/WEB087b923b25abb635430f047f7bebbd6b?method=download&shareKey=64398d4c6780b770074e3f9d3fab43f7) 643 | -------------------------------------------------------------------------------- /myservlet01/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | LearningServlet 7 | com.crzmy 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | myservlet01 13 | war 14 | 15 | myservlet01 Maven Webapp 16 | https://www.crzmy.com 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | myservlet01 26 | 27 | 28 | 29 | maven-clean-plugin 30 | 3.0.0 31 | 32 | 33 | 34 | maven-resources-plugin 35 | 3.0.2 36 | 37 | 38 | maven-compiler-plugin 39 | 3.7.0 40 | 41 | 42 | maven-surefire-plugin 43 | 2.20.1 44 | 45 | 46 | maven-war-plugin 47 | 3.2.0 48 | 49 | 50 | maven-install-plugin 51 | 2.5.2 52 | 53 | 54 | maven-deploy-plugin 55 | 2.8.2 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /myservlet01/src/main/java/AppTest.java: -------------------------------------------------------------------------------- 1 | import java.util.Iterator; 2 | import java.util.Set; 3 | import java.util.TreeSet; 4 | 5 | /** 6 | * 佛祖保佑,此代码无bug, 7 | * 就算有,也一眼看出。 8 | * 9 | * @author ray 10 | * @version 1.0 11 | * @date 2018-07-08 下午6:09 12 | **/ 13 | public class AppTest { 14 | 15 | public static void main(String[] args) { 16 | Set set = new TreeSet<>(); 17 | set.add(5); 18 | set.add(10); 19 | set.add(0); 20 | 21 | Iterator iterator = set.iterator(); 22 | while (iterator.hasNext()){ 23 | System.out.println(iterator.next()); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /myservlet01/src/main/java/com/ray/servlet/App.java: -------------------------------------------------------------------------------- 1 | package com.ray.servlet; 2 | 3 | /** 4 | * 佛祖保佑,此代码无bug, 5 | * 就算有,也一眼看出。 6 | * 7 | * @author ray 8 | * @version 1.0 9 | * @date 2018-07-05 下午8:19 10 | **/ 11 | public class App { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /myservlet01/src/main/java/com/ray/servlet/myservlet/MyServlet.java: -------------------------------------------------------------------------------- 1 | package com.ray.servlet.myservlet; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.http.HttpServlet; 5 | import javax.servlet.http.HttpServletRequest; 6 | import javax.servlet.http.HttpServletResponse; 7 | import java.io.IOException; 8 | import java.io.PrintWriter; 9 | import java.util.Collection; 10 | 11 | /** 12 | * 佛祖保佑,此代码无bug, 13 | * 就算有,也一眼看出。 14 | * 15 | * @author ray 16 | * @version 1.0 17 | * @date 2018-07-05 下午11:24 18 | **/ 19 | public class MyServlet extends HttpServlet { 20 | 21 | public MyServlet() { 22 | super(); 23 | } 24 | 25 | @Override 26 | public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { 27 | PrintWriter pw = response.getWriter(); 28 | pw.println( 29 | "HelloWorld" + 30 | "HelloWorld"+ 31 | ""); 32 | pw.close(); 33 | } 34 | 35 | @Override 36 | public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /myservlet01/src/main/java/com/ray/socket/App.java: -------------------------------------------------------------------------------- 1 | package com.ray.socket; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import java.net.ServerSocket; 7 | import java.net.Socket; 8 | 9 | /** 10 | * 佛祖保佑,此代码无bug, 11 | * 就算有,也一眼看出。 12 | * 13 | * @author ray 14 | * @version 1.0 15 | * @date 2018-07-05 下午10:32 16 | **/ 17 | public class App { 18 | public static void main(String[] args) { 19 | try { 20 | ServerSocket ss = new ServerSocket(8080); 21 | Socket s = ss.accept(); 22 | BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream())); 23 | 24 | // 直接在浏览器输入 localhost:8080 25 | // GET / HTTP/1.1 26 | // Host: localhost:8080 27 | // Connection: keep-alive 28 | // Upgrade-Insecure-Requests: 1 29 | // User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 30 | // Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 31 | // Accept-Encoding: gzip, deflate, br 32 | // Accept-Language: zh-CN,zh;q=0.9 33 | // Cookie: Idea-7798877d=aa86ef31-e4df-4cc6-bf8d-66407314771c 34 | String str; 35 | while ((str = br.readLine()) != null){ 36 | System.out.println(str); 37 | } 38 | } catch (IOException e) { 39 | e.printStackTrace(); 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /myservlet01/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | Archetype Created Web Application 8 | 9 | 10 | myServlet 11 | com.ray.servlet.myservlet.MyServlet 12 | 13 | 14 | 15 | myServlet 16 | /helloWorld.do 17 | 18 | 19 | -------------------------------------------------------------------------------- /myservlet01/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello World!

4 | 5 | 6 | -------------------------------------------------------------------------------- /myservlet02/README.md: -------------------------------------------------------------------------------- 1 | ### 解决乱码问题的三种方式 2 | 3 | #### 第一种 通过jdk 4 | 例子: 5 | ```java 6 | String name = request.getParameter("name"); 7 | // 乱码 8 | System.out.println(name); 9 | name = new String(name.getBytes("iso-8859-1"),"utf-8"); 10 | // 正常 11 | System.out.println(name); 12 | ``` 13 | 这种方式对GET和POST都有效,但是非常的啰嗦冗余,不推荐 14 | 15 | #### 第二种 通过HttpServletRequest 16 | 例子: 17 | ```java 18 | request.setCharacterEncoding("utf-8"); 19 | String name = request.getParameter("name"); 20 | // 正常 21 | System.out.println(name); 22 | ``` 23 | 这种方式只能对POST请求生效,因为GET请求在客户端已经将字节数据通过某种字符集转换成了字符数据,如果再setCharacterEncoding则会更乱 24 | 25 | #### 第三种 通过修改Tomcat配置文件server.xml 26 | 修改Tomcat配置文件server.xml 27 | 在Connector节点添加URIEncoding="utf-8" 28 | ```xml 29 | 33 | ``` 34 | ```java 35 | String value = request.getParameter("name"); 36 | // 正常 37 | System.out.println(value); 38 | ``` -------------------------------------------------------------------------------- /myservlet02/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | LearningServlet 7 | com.crzmy 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | myservlet02 13 | war 14 | 15 | myservlet02 Maven Webapp 16 | https://www.crzmy.com 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | myservlet02 26 | 27 | 28 | 29 | maven-clean-plugin 30 | 3.0.0 31 | 32 | 33 | 34 | maven-resources-plugin 35 | 3.0.2 36 | 37 | 38 | maven-compiler-plugin 39 | 3.7.0 40 | 41 | 42 | maven-surefire-plugin 43 | 2.20.1 44 | 45 | 46 | maven-war-plugin 47 | 3.2.0 48 | 49 | 50 | maven-install-plugin 51 | 2.5.2 52 | 53 | 54 | maven-deploy-plugin 55 | 2.8.2 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /myservlet02/src/main/java/com/ray/MyServlet.java: -------------------------------------------------------------------------------- 1 | package com.ray; 2 | 3 | import javax.servlet.ServletConfig; 4 | import javax.servlet.ServletException; 5 | import javax.servlet.http.HttpServlet; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import java.io.IOException; 9 | import java.io.PrintWriter; 10 | import java.util.Date; 11 | 12 | /** 13 | * 佛祖保佑,此代码无bug, 14 | * 就算有,也一眼看出。 15 | * 16 | * @author ray 17 | * @version 1.0 18 | * @date 2018-07-09 下午3:28 19 | **/ 20 | public class MyServlet extends HttpServlet { 21 | 22 | 23 | @Override 24 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 25 | /*解决中文乱码问题 第二种方式 26 | 只适用于POST请求,使用request里的内置方法*/ 27 | 28 | request.setCharacterEncoding("utf-8"); 29 | String name = request.getParameter("name"); 30 | // 正常 31 | System.out.println(name); 32 | 33 | 34 | } 35 | 36 | @Override 37 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 38 | /*解决中文乱码问题 第一种方式 39 | GET和POST都有效,但不推荐,会有大量冗余代码*/ 40 | 41 | String name = request.getParameter("name"); 42 | // 乱码 43 | System.out.println(name); 44 | name = new String(name.getBytes("iso-8859-1"),"utf-8"); 45 | // 正常 46 | System.out.println(name); 47 | 48 | /*解决中文乱码问题 第三种方式 49 | * 修改Tomcat配置文件server.xml 50 | * 在Connector节点添加URIEncoding="utf-8" 51 | * */ 52 | String value = request.getParameter("name"); 53 | // 正常 54 | System.out.println(value); 55 | } 56 | 57 | @Override 58 | public void destroy() { 59 | System.out.println("MyServlet.destroy"); 60 | } 61 | 62 | @Override 63 | public void init(ServletConfig config) throws ServletException { 64 | System.out.println("MyServlet.init"); 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /myservlet02/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Archetype Created Web Application 7 | 8 | MyServlet 9 | com.ray.MyServlet 10 | 11 | 12 | MyServlet 13 | /helloWorld.do 14 | 15 | 16 | -------------------------------------------------------------------------------- /myservlet02/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: ray 4 | Date: 2018/7/9 5 | Time: 下午3:30 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | Hello World! 12 | 13 | 14 |
15 | 16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /myservlet03/README.md: -------------------------------------------------------------------------------- 1 | ### 获取浏览器附加信息 2 | 3 | 客户端发送Http请求到服务器 4 | 服务器端可以通过HttpServletRequest里的 5 | public Enumeration getHeaderNames(); 6 | 可以获取到客户端的信息的属性名 7 | 然后可以使用方法 8 | public String getHeader(String name); 9 | 获取对应的属性值 10 | -------------------------------------------------------------------------------- /myservlet03/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | LearningServlet 7 | com.crzmy 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | myservlet03 13 | war 14 | 15 | myservlet03 Maven Webapp 16 | https://www.crzmy.com 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | myservlet03 26 | 27 | 28 | 29 | maven-clean-plugin 30 | 3.0.0 31 | 32 | 33 | 34 | maven-resources-plugin 35 | 3.0.2 36 | 37 | 38 | maven-compiler-plugin 39 | 3.7.0 40 | 41 | 42 | maven-surefire-plugin 43 | 2.20.1 44 | 45 | 46 | maven-war-plugin 47 | 3.2.0 48 | 49 | 50 | maven-install-plugin 51 | 2.5.2 52 | 53 | 54 | maven-deploy-plugin 55 | 2.8.2 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /myservlet03/src/main/java/com/ray/MyServlet.java: -------------------------------------------------------------------------------- 1 | package com.ray; 2 | 3 | import javax.servlet.ServletConfig; 4 | import javax.servlet.ServletException; 5 | import javax.servlet.http.HttpServlet; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import java.io.IOException; 9 | import java.io.PrintWriter; 10 | import java.util.Enumeration; 11 | 12 | /** 13 | * 佛祖保佑,此代码无bug, 14 | * 就算有,也一眼看出。 15 | * 16 | * 描述: 17 | * 获取浏览器的附加信息 18 | * 19 | * @author ray 20 | * @version 1.0 21 | * @date 2018-07-09 下午4:24 22 | **/ 23 | public class MyServlet extends HttpServlet { 24 | @Override 25 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 26 | Enumeration enu = request.getHeaderNames(); 27 | // Header信息 28 | // host : localhost:8080 29 | // connection : keep-alive 30 | // content-length : 23 31 | // cache-control : max-age=0 32 | // origin : http://localhost:8080 33 | // upgrade-insecure-requests : 1 34 | // content-type : application/x-www-form-urlencoded 35 | // user-agent : Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36 36 | // accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 37 | // referer : http://localhost:8080/servlet03/ 38 | // accept-encoding : gzip, deflate, br 39 | // accept-language : zh-CN,zh;q=0.9 40 | // cookie : JSESSIONID=71633EB63C57E7FE690C660D2F0BC19F; Idea-7798877d=aa86ef31-e4df-4cc6-bf8d 41 | 42 | 43 | /*输出到页面*/ 44 | // 设置文本类型和编码 45 | response.setContentType("text/html;charset=utf-8"); 46 | 47 | PrintWriter out = response.getWriter(); 48 | out.println(""); 49 | out.println(""); 50 | out.println("My Servlet"); 51 | out.println(""); 52 | out.println(""); 53 | while (enu.hasMoreElements()){ 54 | String property = enu.nextElement(); 55 | out.println(""); 56 | } 57 | out.println("
"+property+""+request.getHeader(property)+"
"); 58 | out.println(""); 59 | out.println(""); 60 | out.close(); 61 | } 62 | 63 | @Override 64 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 65 | this.doPost(request, response); 66 | } 67 | 68 | @Override 69 | public void destroy() { 70 | System.out.println("MyServlet.destroy"); 71 | } 72 | 73 | @Override 74 | public void init(ServletConfig config) throws ServletException { 75 | System.out.println("MyServlet.init"); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /myservlet03/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Archetype Created Web Application 7 | 8 | MyServlet 9 | com.ray.MyServlet 10 | 11 | 12 | MyServlet 13 | /helloWorld.do 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /myservlet03/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: ray 4 | Date: 2018/7/9 5 | Time: 下午3:30 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | Hello World! 12 | 13 | 14 |
15 | 16 | 17 |
18 | 19 | 20 | -------------------------------------------------------------------------------- /myservlet04/README.md: -------------------------------------------------------------------------------- 1 | ### 给客户端返回一个图片并且在浏览器显示 2 | 通过IO流实现,然后注意在setContentType的时候设置响应类型 3 | -------------------------------------------------------------------------------- /myservlet04/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | LearningServlet 7 | com.crzmy 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | myservlet04 13 | war 14 | 15 | myservlet04 Maven Webapp 16 | https://www.crzmy.com 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | myservlet04 26 | 27 | 28 | 29 | maven-clean-plugin 30 | 3.0.0 31 | 32 | 33 | 34 | maven-resources-plugin 35 | 3.0.2 36 | 37 | 38 | maven-compiler-plugin 39 | 3.7.0 40 | 41 | 42 | maven-surefire-plugin 43 | 2.20.1 44 | 45 | 46 | maven-war-plugin 47 | 3.2.0 48 | 49 | 50 | maven-install-plugin 51 | 2.5.2 52 | 53 | 54 | maven-deploy-plugin 55 | 2.8.2 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /myservlet04/src/banana.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhu811/learning-servlet/b678139fc00cea7a24f39bfab3aa1b44d7b4a363/myservlet04/src/banana.png -------------------------------------------------------------------------------- /myservlet04/src/main/java/com/ray/MyServlet.java: -------------------------------------------------------------------------------- 1 | package com.ray; 2 | 3 | import javax.servlet.ServletConfig; 4 | import javax.servlet.ServletException; 5 | import javax.servlet.http.HttpServlet; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import java.io.*; 9 | 10 | /** 11 | * 佛祖保佑,此代码无bug, 12 | * 就算有,也一眼看出。 13 | * 14 | * @author ray 15 | * @version 1.0 16 | * @date 2018-07-09 下午6:57 17 | **/ 18 | public class MyServlet extends HttpServlet { 19 | 20 | @Override 21 | protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 22 | this.doPost(req,resp); 23 | } 24 | 25 | @Override 26 | protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 27 | InputStream fis = new FileInputStream(new File("/Users/ray/IdeaProjects/LearningServlet/myservlet04/src/banana.png")); 28 | byte[] buf = new byte[1024]; 29 | int len; 30 | OutputStream fos = resp.getOutputStream(); 31 | resp.setContentType("image/webp"); 32 | while ((len = fis.read(buf)) != -1){ 33 | fos.write(buf, 0, len); 34 | } 35 | 36 | fis.close(); 37 | fos.close(); 38 | } 39 | 40 | @Override 41 | public void destroy() { 42 | System.out.println("MyServlet.destroy"); 43 | } 44 | 45 | @Override 46 | public void init(ServletConfig config) throws ServletException { 47 | System.out.println("MyServlet.init"); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /myservlet04/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Archetype Created Web Application 7 | 8 | MyServlet 9 | com.ray.MyServlet 10 | 11 | 12 | 13 | MyServlet 14 | /helloWorld.do 15 | 16 | 17 | -------------------------------------------------------------------------------- /myservlet04/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | 2 | 3 |

Hello World!

4 | 5 | 6 | -------------------------------------------------------------------------------- /myservlet05/README.md: -------------------------------------------------------------------------------- 1 | ### 文件下载 -------------------------------------------------------------------------------- /myservlet05/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | LearningServlet 7 | com.crzmy 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | myservlet05 13 | war 14 | 15 | myservlet05 Maven Webapp 16 | https://www.crzmy.com 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | myservlet04 26 | 27 | 28 | 29 | maven-clean-plugin 30 | 3.0.0 31 | 32 | 33 | 34 | maven-resources-plugin 35 | 3.0.2 36 | 37 | 38 | maven-compiler-plugin 39 | 3.7.0 40 | 41 | 42 | maven-surefire-plugin 43 | 2.20.1 44 | 45 | 46 | maven-war-plugin 47 | 3.2.0 48 | 49 | 50 | maven-install-plugin 51 | 2.5.2 52 | 53 | 54 | maven-deploy-plugin 55 | 2.8.2 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | -------------------------------------------------------------------------------- /myservlet05/src/main/java/com/ray/MyServlet.java: -------------------------------------------------------------------------------- 1 | package com.ray; 2 | 3 | import javax.servlet.ServletConfig; 4 | import javax.servlet.ServletException; 5 | import javax.servlet.http.HttpServlet; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import java.io.*; 9 | 10 | /** 11 | * 佛祖保佑,此代码无bug, 12 | * 就算有,也一眼看出。 13 | * 14 | * @author ray 15 | * @version 1.0 16 | * @date 2018-07-09 下午7:43 17 | **/ 18 | public class MyServlet extends HttpServlet { 19 | 20 | @Override 21 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 22 | String path = getServletContext().getRealPath("/spring-mvc官方手册.pdf"); 23 | File file = new File(path); 24 | InputStream fis = new FileInputStream(path); 25 | byte[] buf = new byte[1024]; 26 | int len; 27 | OutputStream fos = response.getOutputStream(); 28 | // 响应二进制内容 29 | response.setContentType("bin"); 30 | // 包装一层iso-8859-1的外衣,当客户端下载的时候解码,就是原来的utf-8的文件名,不会中文乱码 31 | String fileName = new String(file.getName().getBytes("utf-8"),"iso-8859-1"); 32 | response.addHeader("Content-disposition", "attachment;filename=\""+fileName+"\""); 33 | while ((len = fis.read(buf)) != -1){ 34 | fos.write(buf, 0, len); 35 | } 36 | fis.close(); 37 | fos.close(); 38 | } 39 | 40 | @Override 41 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 42 | this.doPost(request, response); 43 | } 44 | 45 | @Override 46 | public void destroy() { 47 | System.out.println("MyServlet.destroy"); 48 | } 49 | 50 | @Override 51 | public void init(ServletConfig config) throws ServletException { 52 | super.init(config); 53 | System.out.println("MyServlet.init"); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /myservlet05/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Archetype Created Web Application 7 | 8 | 9 | MyServlet 10 | com.ray.MyServlet 11 | 12 | 13 | MyServlet 14 | /helloWorld.do 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /myservlet05/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ page import="java.util.Date" %> 2 | <%@ page import="java.text.SimpleDateFormat" %> 3 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 4 | 5 | 6 | Title 7 | 8 | 9 | <%= new Date()%> 10 | 11 | <%! 12 | int anInt = 20180713; 13 | %> 14 | 15 | <% 16 | Date date = new Date(); 17 | SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 18 | out.println(sdf.format(date)); 19 | %> 20 | 21 | 22 | -------------------------------------------------------------------------------- /myservlet05/src/main/webapp/spring-mvc官方手册.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mozhu811/learning-servlet/b678139fc00cea7a24f39bfab3aa1b44d7b4a363/myservlet05/src/main/webapp/spring-mvc官方手册.pdf -------------------------------------------------------------------------------- /myservlet06/myservlet06.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /myservlet06/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | LearningServlet 7 | com.crzmy 8 | 1.0-SNAPSHOT 9 | 10 | 4.0.0 11 | 12 | myservlet06 13 | war 14 | 15 | myservlet06 Maven Webapp 16 | https://www.crzmy.com 17 | 18 | 19 | UTF-8 20 | 1.8 21 | 1.8 22 | 23 | 24 | 25 | 26 | junit 27 | junit 28 | 4.11 29 | 30 | 31 | 32 | mysql 33 | mysql-connector-java 34 | 8.0.16 35 | 36 | 37 | 38 | 39 | myservlet06 40 | 41 | 42 | 43 | maven-clean-plugin 44 | 3.0.0 45 | 46 | 47 | 48 | maven-resources-plugin 49 | 3.0.2 50 | 51 | 52 | maven-compiler-plugin 53 | 3.7.0 54 | 55 | 56 | maven-surefire-plugin 57 | 2.20.1 58 | 59 | 60 | maven-war-plugin 61 | 3.2.0 62 | 63 | 64 | maven-install-plugin 65 | 2.5.2 66 | 67 | 68 | maven-deploy-plugin 69 | 2.8.2 70 | 71 | 72 | 73 | 74 | 75 | 76 | ${basedir}/src/main/java 77 | 78 | **/*.properties 79 | **/*.xml 80 | 81 | 82 | 83 | ${basedir}/src/main/resources 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /myservlet06/src/main/java/com/ray/entity/User.java: -------------------------------------------------------------------------------- 1 | package com.ray.entity; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * 佛祖保佑,此代码无bug, 7 | * 就算有,也一眼看出。 8 | * 9 | * @author ray 10 | * @version 1.0 11 | * @date 2018-07-14 上午1:41 12 | **/ 13 | public class User implements Serializable { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /myservlet06/src/main/java/com/ray/servlet/UserServlet.java: -------------------------------------------------------------------------------- 1 | package com.ray.servlet; 2 | 3 | import javax.servlet.ServletException; 4 | import javax.servlet.annotation.WebServlet; 5 | import javax.servlet.http.HttpServlet; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import java.io.IOException; 9 | 10 | /** 11 | * 佛祖保佑,此代码无bug, 12 | * 就算有,也一眼看出。 13 | * 14 | * @author ray 15 | * @version 1.0 16 | * @date 2018-07-14 上午1:42 17 | **/ 18 | @WebServlet(name = "UserServlet") 19 | public class UserServlet extends HttpServlet { 20 | 21 | @Override 22 | protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 23 | 24 | } 25 | 26 | @Override 27 | protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /myservlet06/src/main/java/com/ray/utils/DbConfig.java: -------------------------------------------------------------------------------- 1 | package com.ray.utils; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.io.IOException; 6 | import java.io.InputStream; 7 | import java.util.Enumeration; 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | import java.util.Properties; 11 | 12 | /** 13 | * 佛祖保佑,此代码无bug, 14 | * 就算有,也一眼看出。 15 | * 16 | * @author ray 17 | * @version 1.0 18 | * @date 2018-07-14 上午1:15 19 | **/ 20 | public class DbConfig { 21 | 22 | private static Map config = null; 23 | 24 | public static Map getConfig(String path){ 25 | if (config == null){ 26 | config = new HashMap<>(16); 27 | try { 28 | InputStream fis = DbConfig.class.getClassLoader().getResourceAsStream(path); 29 | Properties prop = new Properties(); 30 | prop.load(fis); 31 | Enumeration keys = prop.propertyNames(); 32 | while (keys.hasMoreElements()){ 33 | String key = (String) keys.nextElement(); 34 | config.put(key, prop.getProperty(key)); 35 | } 36 | return config; 37 | } catch (IOException e) { 38 | e.printStackTrace(); 39 | } 40 | } 41 | return config; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /myservlet06/src/main/java/com/ray/utils/DbUtils.java: -------------------------------------------------------------------------------- 1 | package com.ray.utils; 2 | 3 | 4 | import java.io.IOException; 5 | import java.sql.Connection; 6 | import java.sql.DriverManager; 7 | import java.sql.SQLException; 8 | import java.util.Map; 9 | 10 | /** 11 | * 佛祖保佑,此代码无bug, 12 | * 就算有,也一眼看出。 13 | * 14 | * 描述: 15 | * 数据库工具类 16 | * 17 | * @author ray 18 | * @version 1.0 19 | * @date 2018-07-14 上午1:11 20 | **/ 21 | public class DbUtils { 22 | 23 | private static Connection connection = null; 24 | 25 | public static Connection getConnection(){ 26 | if (connection == null){ 27 | Map config = null; 28 | try { 29 | config = DbConfig.getConfig("db.properties"); 30 | Class.forName(config.get("jdbc.driverClass")); 31 | String url = config.get("jdbc.url"); 32 | String user = config.get("jdbc.user"); 33 | String pwd = config.get("jdbc.password"); 34 | connection = DriverManager.getConnection(url, user, pwd); 35 | return connection; 36 | } catch (SQLException | ClassNotFoundException e) { 37 | e.printStackTrace(); 38 | } 39 | 40 | } 41 | return connection; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /myservlet06/src/main/resources/db.properties: -------------------------------------------------------------------------------- 1 | jdbc.driverClass=com.mysql.jdbc.Driver 2 | jdbc.url=jdbc:mysql://localhost:3306/servletTest?useUnicode=true&characterEncoding=utf-8&useSSL=false 3 | jdbc.user=root 4 | jdbc.password=123456 -------------------------------------------------------------------------------- /myservlet06/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | Archetype Created Web Application 7 | 8 | userServlet 9 | com.ray.servlet.UserServlet 10 | 11 | 12 | 13 | userServlet 14 | *.do 15 | 16 | 17 | -------------------------------------------------------------------------------- /myservlet06/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%-- 2 | Created by IntelliJ IDEA. 3 | User: ray 4 | Date: 2018/7/14 5 | Time: 上午12:57 6 | To change this template use File | Settings | File Templates. 7 | --%> 8 | <%@ page contentType="text/html;charset=UTF-8" language="java" %> 9 | 10 | 11 | 登录 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /myservlet06/src/test/DbTest.java: -------------------------------------------------------------------------------- 1 | import com.ray.utils.DbUtils; 2 | import org.junit.Test; 3 | 4 | import java.sql.*; 5 | 6 | /** 7 | * 佛祖保佑,此代码无bug, 8 | * 就算有,也一眼看出。 9 | * 10 | * @author ray 11 | * @version 1.0 12 | * @date 2018-07-14 上午1:44 13 | **/ 14 | public class DbTest { 15 | 16 | @Test 17 | public void dbTest() throws SQLException { 18 | Connection c = DbUtils.getConnection(); 19 | String sql = "select uUsername from user where uId = ?"; 20 | PreparedStatement ps = c.prepareStatement(sql); 21 | ps.setInt(1,1); 22 | ResultSet rs = ps.executeQuery(); 23 | while (rs.next()){ 24 | System.out.println(rs.getString(1)); 25 | } 26 | 27 | rs.close(); 28 | ps.close(); 29 | c.close(); 30 | } 31 | 32 | @Test 33 | public void getPath(){ 34 | System.out.println(System.getProperty("user.dir")); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 4.0.0 6 | 7 | com.crzmy 8 | LearningServlet 9 | 1.0-SNAPSHOT 10 | 11 | myservlet01 12 | myservlet02 13 | myservlet03 14 | myservlet04 15 | myservlet05 16 | myservlet06 17 | 18 | pom 19 | 20 | LearningServlet Maven Webapp 21 | https://www.crzmy.com 22 | 23 | 24 | UTF-8 25 | 1.8 26 | 1.8 27 | 28 | 29 | 30 | 31 | junit 32 | junit 33 | 4.11 34 | 35 | 36 | 37 | javax.servlet 38 | javax.servlet-api 39 | 3.1.0 40 | provided 41 | 42 | 43 | 44 | 45 | javax.servlet.jsp 46 | jsp-api 47 | 2.1 48 | provided 49 | 50 | 51 | 52 | mysql 53 | mysql-connector-java 54 | 8.0.16 55 | 56 | 57 | 58 | 59 | LearningServlet 60 | 61 | 62 | 63 | maven-clean-plugin 64 | 3.0.0 65 | 66 | 67 | 68 | maven-resources-plugin 69 | 3.0.2 70 | 71 | 72 | maven-compiler-plugin 73 | 3.7.0 74 | 75 | 76 | maven-surefire-plugin 77 | 2.20.1 78 | 79 | 80 | maven-war-plugin 81 | 3.2.0 82 | 83 | 84 | maven-install-plugin 85 | 2.5.2 86 | 87 | 88 | maven-deploy-plugin 89 | 2.8.2 90 | 91 | 92 | 93 | 94 | 95 | 96 | src/main/java 97 | 98 | **/*.xml 99 | 100 | true 101 | 102 | 103 | src/main/resources 104 | 105 | 106 | 107 | 108 | --------------------------------------------------------------------------------