文章目录 1.nginx的conf文件:以前网络编程中B/S架构中服务器是用socket写,用文件输入流读一个文件,读到后socket通过outputstream写出去,这些过程有了nginx后再也不用写 2.nginx反向代理与负载均衡:nginx是被广泛使用的网页服务器,在www.163.com的F12的Network中Headers中有server:nginx,使用nginx首当其冲,做反向代理,将请求分发到公司的多台服务器上 2.1 location匹配方式:location / 默认匹配所有请求,相当于第四优先级(最弱) 2.2 反向代理写法:http80, 2.3 负载均衡写法:基于反向代理 3.服务器:软件为tomcat或nginx,程序为servlet 4.servlet:多态,web.xml 5.servlet生命周期:LifecycleServlet 6.servlet优化:GenericServelt/HttpServelt 7.http协议和抓包:枚举Enumeration,request.getHeaderNames() 8.request对象:.getParameterMap(),post请求中文参数乱码 9.请求转发:jrss,request.setAttribute() 10.登陆案例(1):成功和失败页面相当于两个模块 11.response对象:text/html,重定向(.setStatus,.setHeader) 12.文件下载:request/response
1.nginx的conf文件:以前网络编程中B/S架构中服务器是用socket写,用文件输入流读一个文件,读到后socket通过outputstream写出去,这些过程有了nginx后再也不用写
nginx软件链接:https://pan.baidu.com/s/1zvF2irI6OenDKVfvSIOZmg ,提取码:gsn9。 如果http协议是80端口的话,80端口会被隐藏,本机浏览器输入http://localhost:80启动服务端显示如下,hello nginx是E\my81\index.html里内容。本机ipconfig显示192.168.33.71。上面红框浏览器(客户端)是别人的电脑【局域网下同一网段】,上面两个大框是服务端,浏览器和服务器三要素对应。 nginx作用:1.反向代理:s被代理1个公网ip,但有n台s对外服务。 2.负载均衡:基于反向代理。 3.正向代理:我们电脑接入VPN 后,我们对外IP地址就会变成VPN服务器的公网IP。 4.动静分离:网页f12显示js,css,img属静态数据。
线程通讯:volatile关键字,wait(),notify() 线程安全:synchronized关键字 计算密集型:进行(多核) io密集型:线/协程(只1个核在做,占资源轻,io等待时间拿来用)
2.nginx反向代理与负载均衡:nginx是被广泛使用的网页服务器,在www.163.com的F12的Network中Headers中有server:nginx,使用nginx首当其冲,做反向代理,将请求分发到公司的多台服务器上
原生nginx没有集成很多插件,使用不方便。推荐使用openresty(在nginx基础上集成了很多lua写的插件),官网下载openresty后解压后进一级目录输入nginx.exe回车运行服务端,浏览器输入localhost默认:80端口。修改conf目录下nginx.conf文件,删除注释。50x.html是错误页面,暂时不用。 如下还是在nginx.conf文件里,stream类型执行下载,echo是插件。
2.1 location匹配方式:location / 默认匹配所有请求,相当于第四优先级(最弱)
1.如下最强级别=。 2.如下优先级第二,^~以什么开头。如下/是路径,不是转义符。 3.如下优先级第三,正则表达式~。\w匹配数字、字母、下划线,转义字符\可以转义很多字符,比如\n表示换行,\t表示制表符,字符\本身也要转义,所以\\表示的字符就是\。如下/是路径。 如下同优先级的,按匹配程度较高的先匹配。 同优先级并且匹配程度相同的话,写在上面的优先执行。
2.2 反向代理写法:http80,
如下是其他服务器,记住192…:80是it works页面。 如下localhost先到本机127.0.0.0,再转到192上面的这个服务器。 如下是apach返回的Not Found返回的信息,192…:80/a路径没有,不是nginx返回的信息,因为已经把请求转到192… 1.默认拼接。 如下其实转到了192...:80/a。 2.如下转到192...:80/,两个/省去后一个字母。
2.3 负载均衡写法:基于反向代理
两个ip+端口根据权重切换。
3.服务器:软件为tomcat或nginx,程序为servlet
Web(World Wide Web)即全球广域网,也称为万维网。 nginx不支持java规范,tomcat支持。tomcat8:https://tomcat.apache.org/download-80.cgi。免安装,解压即可用:链接:https://pan.baidu.com/s/1UJM9kbIHGIXkNXlYLpcoGw ,提取码:g610。dos系统识别文件后缀名不能超过3位(先有dos后有windows),所以.htm。8080一般是用来连接代理的(8080不能省,只有80才能省)。 只有index.html是默认的,不用加在最后,localhost:8080/a.html。 如下javaee新建项目,apache-tomcat8…是前面tomcat软件解压路径。如下不需要自己开启tomcat,idea配置自动开启。 如下New和上面一样,关联tomcat软件解压路径。 如下将web文件夹当成前端static web项目,web文件夹里都可以访问,除了web-info无法访问(如【Mysql3】最后一节,-info文件夹放jar包),Toolbar工具栏。 如下是点乌龟运行后,浏览器自动打开的原理。改变路径 / 写法。 如上若还是不会默认打开谷歌,需要File - Settings - Tools - Web Browsers。
4.servlet:多态,web.xml
如下选中src右击new - java class,name为com.itheima01.servlet.MyServlet,还有一件事配置web.xml如上图所示。
package com. itheima01. servlet ;
import javax. servlet. * ;
import java. io. IOException ; public class MyServlet implements Servlet { @Override public void service ( ServletRequest servletRequest
, ServletResponse servletResponse
) throws ServletException , IOException { System . out
. println ( "控制台日志: 服务器被访问了" ) ; servletResponse
. getWriter ( ) . print ( "hello servlet" ) ; } @Override public void init ( ServletConfig servletConfig
) throws ServletException { } @Override public ServletConfig getServletConfig ( ) { return null ; } @Override public String getServletInfo ( ) { return null ; } @Override public void destroy ( ) { }
}
如下点击idea中乌龟,自动打开网页,改变/my路径。 tomcat+servlet原理(4步):以前解析xml文件(web.xml)用dom4j,将xml先读到内存里在进行解析。第4步:mapping映射后,tomcat(中介即代理默认端口8080)底层会进行反射,当前类com.itheima01.servlet.MyServlet肯定是Servlet接口的implements实现类,可以向上转型,父类Servlet调用方法执行子类重新的方法。
为什么tomcat底层用反射?tomcat底层设计不能和MyServlet耦合,只有全限定名和MyServlet有关(自己设定的),通用性。tomcat像管家中介(用户,tomcat软件【中介】,jdk的Servlet)在第3步等客人,第4步客人来了找my,tomcat根据客人请求找到my的住址com....MyServlet,把my叫醒进行service办公。
如上在web.xml中,MyServlet01可以随便命名但要上下一致,my是资源位置,/my(因为在当前项目,http…8080可以省略,url)和com…MyServlet(class,全限定名就是全类名就是包名加类名)对应关系。
5.servlet生命周期:LifecycleServlet
package com. itheima02. life ;
import javax. servlet. * ;
import java. io. IOException ; public class LifecycleServlet implements Servlet { public LifecycleServlet ( ) { System . out
. println ( "LifecycleServlet" ) ; } @Override public void init ( ServletConfig servletConfig
) throws ServletException { System . out
. println ( "init" ) ; } @Override public void service ( ServletRequest servletRequest
, ServletResponse servletResponse
) throws ServletException , IOException { System . out
. println ( "service" ) ; } @Override public void destroy ( ) { System . out
. println ( "destroy" ) ; } @Override public ServletConfig getServletConfig ( ) { System . out
. println ( "getServletConfig" ) ; return null ; } @Override public String getServletInfo ( ) { System . out
. println ( "getServletInfo" ) ; return null ; }
}
//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/javaeehttp://java.sun.com/xml/ns/javaee/web-app_3_1.xsd" version = " 3.1" > < servlet> < servlet-name> MyServlet01
</ servlet-name> < servlet-class> com.itheima01.servlet.MyServlet
</ servlet-class> </ servlet> < servlet-mapping> < servlet-name> MyServlet01
</ servlet-name> < url-pattern> /my
</ url-pattern> </ servlet-mapping> < servlet> < servlet-name> LifecycleServlet
</ servlet-name> < servlet-class> com.itheima02.life.LifecycleServlet
</ servlet-class> </ servlet> < servlet-mapping> < servlet-name> LifecycleServlet
</ servlet-name> < url-pattern> /life
</ url-pattern> </ servlet-mapping> < servlet> < servlet-name> GoodServlet
</ servlet-name> < servlet-class> com.itheima03.good.GoodServlet
</ servlet-class> </ servlet> < servlet-mapping> < servlet-name> GoodServlet
</ servlet-name> < url-pattern> /good
</ url-pattern> </ servlet-mapping> < servlet> < servlet-name> BetterServlet
</ servlet-name> < servlet-class> com.itheima03.good.BetterServlet
</ servlet-class> </ servlet> < servlet-mapping> < servlet-name> BetterServlet
</ servlet-name> < url-pattern> /better
</ url-pattern> </ servlet-mapping>
</ web-app>
如下默认调用空参构造创建实例(第一行)。
6.servlet优化:GenericServelt/HttpServelt
只留一个接口叫适配器设计模式。将service方法根据不同请求方式分化出两个不同方法。
package com. itheima03. good ;
import javax. servlet. GenericServlet ;
import javax. servlet. ServletException ;
import javax. servlet. ServletRequest ;
import javax. servlet. ServletResponse ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ; public class GoodServlet extends GenericServlet {
@Override public void service ( ServletRequest servletRequest
, ServletResponse servletResponse
) throws ServletException , IOException { System . out
. println ( "goodServlet" ) ; HttpServletRequest request
= ( HttpServletRequest ) servletRequest
; HttpServletResponse response
= ( HttpServletResponse ) servletResponse
; service2 ( request
, response
) ; } private void service2 ( HttpServletRequest request
, HttpServletResponse response
) { String method
= request
. getMethod ( ) ; if ( "GET" . equals ( method
) ) { doGet ( request
, response
) ; } else if ( "POST" . equals ( method
) ) { doPost ( request
, response
) ; } } private void doPost ( HttpServletRequest request
, HttpServletResponse response
) { } private void doGet ( HttpServletRequest request
, HttpServletResponse response
) { }
}
浏览器:localhost:8080/good,网页无显示,控制台打印goodServlet。
package com. itheima03. good ;
import javax. servlet. ServletException ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ; public class BetterServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest req
, HttpServletResponse resp
) throws ServletException , IOException { doGet ( req
, resp
) ; } @Override protected void doGet ( HttpServletRequest req
, HttpServletResponse resp
) throws ServletException , IOException { }
}
如上解决了前二个问题。如下解决第三个问题,不用配置web.xml。
package com. itheima03. good ;
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ; @WebServlet ( urlPatterns
= "/best" )
public class BestServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest req
, HttpServletResponse resp
) throws ServletException , IOException { doGet ( req
, resp
) ; } @Override protected void doGet ( HttpServletRequest req
, HttpServletResponse resp
) throws ServletException , IOException { System . out
. println ( "被访问了" ) ; }
}
如下把上面BestServlet类设置为模板,使用:选中包(包下)-new-servlet。 如上模板如下:
#
if ( $
{ PACKAGE_NAME
} && $
{ PACKAGE_NAME
} != "" ) package $
{ PACKAGE_NAME
} ; #end
#
parse ( "File Header.java" ) @javax.servlet.annotation.WebServlet ( urlPatterns
= "/${Entity_Name}" )
public class $
{ Class_Name } extends javax. servlet. http. HttpServlet { @Override protected void doPost ( javax. servlet. http. HttpServletRequest request
, javax. servlet. http. HttpServletResponse response
) throws javax. servlet. ServletException, java. io. IOException { doGet ( request
, response
) ; } @Override protected void doGet ( javax. servlet. http. HttpServletRequest request
, javax. servlet. http. HttpServletResponse response
) throws javax. servlet. ServletException, java. io. IOException { }
}
7.http协议和抓包:枚举Enumeration,request.getHeaderNames()
http的request对象:由tomcat创建,并且里面数据由tomcat set进去,我们只需要get出来。 File-New-Project-Java Enterprise。
<! DOCTYPE html >
< html lang = " en" >
< head> < meta charset = " UTF-8" > < title> Title
</ title>
</ head>
< body> < h1> get请求方式
</ h1> < form action = " http://localhost:8080/MyServlet" method = " get" > < input type = " text" placeholder = " 请输入用户名" name = " name" > < br> < input type = " text" placeholder = " 请输入密码" name = " pwd" > < br> < input type = " submit" > </ form> < h1> post请求方式
</ h1> < form action = " /MyServlet" method = " post" > < input type = " text" placeholder = " 请输入用户名" name = " name" > < br> < input type = " text" placeholder = " 请输入密码" name = " pwd" > < br> < input type = " submit" > </ form>
</ body>
</ html>
如上html文件建在web文件夹路径下,如下创建的是servlet的模板。
package com. itheima01. http ;
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ;
import java. util. * ;
@WebServlet ( urlPatterns
= "/MyServlet" )
public class MyServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException {
String agent
= request
. getHeader ( "user-agent" ) ; String referer
= request
. getHeader ( "referer" ) ; System . out
. println ( agent
) ; System . out
. println ( referer
) ; HashMap < String , String > map
= new HashMap < > ( ) ; Iterator < String > it
= map
. keySet ( ) . iterator ( ) ; while ( it
. hasNext ( ) ) { String key
= it
. next ( ) ; String value
= map
. get ( key
) ; } Enumeration < String > it2
= request
. getHeaderNames ( ) ; while ( it2
. hasMoreElements ( ) ) { String name
= it2
. nextElement ( ) ; String value
= request
. getHeader ( name
) ; System . out
. println ( name
+ "->" + value
) ; } } private void line ( HttpServletRequest request
) { String method
= request
. getMethod ( ) ; StringBuffer url
= request
. getRequestURL ( ) ; String protocol
= request
. getProtocol ( ) ; String remoteAddr
= request
. getRemoteAddr ( ) ; System . out
. println ( method
) ; System . out
. println ( url
. toString ( ) ) ; System . out
. println ( protocol
) ; System . out
. println ( "访问者的ip:" + remoteAddr
) ; }
}
如上浏览器网址中…报文.html是Referer中的上一次访问页面,因为已跳转到如下下个页面。 如下请求行中的请求url省略了如上的http://localhost:8080。cookie是浏览器缓存的一种。get请求中最后一行不是请求体,是谷歌浏览器工具抓包进行的参数强调渲染。
8.request对象:.getParameterMap(),post请求中文参数乱码
<! DOCTYPE html >
< html lang = " en" >
< head> < meta charset = " UTF-8" > < title> Title
</ title>
</ head>
< body> < h1> get请求
</ h1> < form action = " /ParamServlet" method = " get" > 用户名:
< input type = " text" name = " name" > < br> 密码:
< input type = " password" name = " pwd" > < br> 性别:
< input type = " radio" name = " gender" value = " boy" > 男
< input type = " radio" name = " gender" value = " girl" > 女
< br> 爱好:
< input type = " checkbox" name = " hobby" value = " smoke" > 抽烟
< input type = " checkbox" name = " hobby" value = " drink" > 喝酒
< input type = " checkbox" name = " hobby" value = " firehead" > 烫头
< br> < input type = " submit" > </ form> < h1> post请求
</ h1> < form action = " /ParamServlet" method = " post" > 用户名:
< input type = " text" name = " name" > < br> 密码:
< input type = " password" name = " pwd" > < br> 性别:
< input type = " radio" name = " gender" value = " boy" > < input type = " radio" name = " gender" value = " girl" > < br> 爱好:
< input type = " checkbox" name = " hobby" value = " smoke" > 抽烟
< input type = " checkbox" name = " hobby" value = " drink" > 喝酒
< input type = " checkbox" name = " hobby" value = " firehead" > 烫头
< br> < input type = " submit" > </ form>
</ body>
</ html>
package com. itheima02. param ;
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ;
import java. util. Arrays ;
import java. util. Map ;
import java. util. Set ;
@WebServlet ( urlPatterns
= "/ParamServlet" )
public class ParamServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { request
. setCharacterEncoding ( "utf-8" ) ; doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException {
String name
= request
. getParameter ( "name" ) ; String pwd
= request
. getParameter ( "pwd" ) ; String gender
= request
. getParameter ( "gender" ) ; String [ ] hobbies
= request
. getParameterValues ( "hobby" ) ; System . out
. println ( name
+ "," + pwd
+ "," + gender
+ "," + Arrays . toString ( hobbies
) ) ; Map < String , String [ ] > map
= request
. getParameterMap ( ) ;
Set < String > set
= map
. keySet ( ) ; for ( String key
: set
) { String [ ] value
= map
. get ( key
) ;
} }
}
如下选中的是map遍历出来的结果和下面第一行一样。
9.请求转发:jrss,request.setAttribute()
request表面上获取请求数据,还有快递员身份。 如下forward方法中request是邮件及内容,response是回应权限。A模块指MyServlet,B模块指ZhouServlet。一次请求链如下只有一去一回。
<! DOCTYPE html >
< html lang = " en" >
< head> < meta charset = " UTF-8" > < title> Title
</ title>
</ head>
< body> 人事
< a href = " /ShiServlet?msg=有人来面试" > 发送邮件
</ a>
</ body>
</ html>
package com. itheima03. transfer ;
import javax. servlet. RequestDispatcher ;
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ; @WebServlet ( urlPatterns
= "/ShiServlet" )
public class ShiServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String msg
= request
. getParameter ( "msg" ) ; System . out
. println ( "shi:" + msg
) ; System . out
. println ( "shi:我现在没空,叫周楠同学帮我面试" ) ; request
. setAttribute ( "extra" , "比我帅的不要~~" ) ;
request
. getRequestDispatcher ( "/ZhouServlet" ) . forward ( request
, response
) ; }
}
package com. itheima03. transfer ;
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ; @WebServlet ( urlPatterns
= "/ZhouServlet" )
public class ZhouServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String msg
= request
. getParameter ( "msg" ) ; System . out
. println ( "zhou:" + msg
) ; Object extra
= request
. getAttribute ( "extra" ) ; System . out
. println ( "zhou:" + extra
) ; System . out
. println ( "周楠同学放下手机,难得做点事情: 面试" ) ; response
. getWriter ( ) . print ( "this boy is ok,about 3k~~" ) ; }
}
10.登陆案例(1):成功和失败页面相当于两个模块
File - New - Project - Java Enterprise。 如下想到Junit包失效。
package com. itheima. utils ;
import com. mchange. v2. c3p0. ComboPooledDataSource ;
import org. springframework. jdbc. core. JdbcTemplate ; public class JdbcUtil { private static ComboPooledDataSource ds
= new ComboPooledDataSource ( ) ; public static JdbcTemplate getTemplate ( ) { JdbcTemplate template
= new JdbcTemplate ( ds
) ; return template
; }
}
package com. itheima. login ;
import com. itheima. bean. User ;
import com. itheima. utils. JdbcUtil ;
import com. mchange. v2. c3p0. ComboPooledDataSource ;
import org. springframework. dao. DataAccessException ;
import org. springframework. jdbc. core. BeanPropertyRowMapper ;
import org. springframework. jdbc. core. JdbcTemplate ;
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ; @WebServlet ( urlPatterns
= "/LoginServlet" )
public class LoginServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String username
= request
. getParameter ( "userName" ) ; String password
= request
. getParameter ( "password" ) ; String sql
= "select * from user where username = ? and password = ?" ; JdbcTemplate template
= JdbcUtil . getTemplate ( ) ; User user
= template
. queryForObject ( sql
, new BeanPropertyRowMapper < > ( User . class ) , username
, password
) ; if ( user
!= null ) { request
. getRequestDispatcher ( "/success.html" ) . forward ( request
, response
) ; } else { request
. getRequestDispatcher ( "/error.html" ) . forward ( request
, response
) ; } }
}
package com. itheima. bean ; public class User { private Integer id
; private String username
; private String password
; @Override public String toString ( ) { return "User{" + "id=" + id
+ ", username='" + username
+ '\'' + ", password='" + password
+ '\'' + '}' ; } public Integer getId ( ) { return id
; } public void setId ( Integer id
) { this . id
= id
; } public String getUsername ( ) { return username
; } public void setUsername ( String username
) { this . username
= username
; } public String getPassword ( ) { return password
; } public void setPassword ( String password
) { this . password
= password
; }
}
//login.html
<! DOCTYPE html >
< html lang = " en" >
< head> < meta charset = " utf-8" > < meta http-equiv = " X-UA-Compatible" content = " IE=edge" > < meta name = " viewport" content = " width=device-width, initial-scale=1" > < title> 登录页面
</ title> < link href = " css/bootstrap.min.css" rel = " stylesheet" > < link href = " css/login.css" rel = " stylesheet" > < script src = " js/jquery.js" > </ script> < script src = " js/bootstrap.js" > </ script>
</ head>
< body> < div class = " container text-center" > < form class = " form-signin" action = " /LoginServlet" > < h2 class = " form-signin-heading" > 登录页面
</ h2> < input type = " text" name = " userName" class = " form-control" placeholder = " 用户名" required autofocus > < input type = " password" name = " password" class = " form-control" placeholder = " 密码" required > < button class = " btn btn-lg btn-primary btn-block" type = " submit" > 登录
</ button> </ form> </ div>
</ body>
</ html>
11.response对象:text/html,重定向(.setStatus,.setHeader)
package com. itheima01. http ;
import javax. servlet. ServletException ;
import javax. servlet. ServletOutputStream ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ;
import java. io. PrintWriter ; @WebServlet ( urlPatterns
= "/MyServlet" )
public class MyServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { System . out
. println ( "服务器被访问了" ) ;
response
. setStatus ( 302 ) ;
}
}
请求报文分get和post两种,在响应报文里看到了非servlet设置的内容,那就是tomcat设置的。将前端改为href=“/MyServlet123”,则会出现404。servlet关了,tomcat自动设置为500状态码。
如下体中hello response长度一共为Content-Lenth为14,头中GMT格林位置需+8小时为东八区北京时间。如下行和头都是tomcat默认自动设置,体是我们servlet手动设置。想修改状态码,需要在servlet(对我们暴露的小程序)中修改。 如下响应头分四种(蓝色字),如下简易API等同上行。 如下点击后,5秒后跳转到百度。
package com. itheima02. header ;
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ; @WebServlet ( urlPatterns
= "/RefreshAndTypeServlet" )
public class RefreshAndTypeServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { System . out
. println ( "服务器被访问了" ) ;
response
. setContentType ( "text/html;charset=utf-8" ) ; response
. getWriter ( ) . print ( "<h1>哈哈</h1>" ) ; }
}
因为重定向不是一次请求链,所以超过域对象,不能用request传递数据。ZhouServlet收不到人事的msg,能收到ShiServlet的response.setHeader(…/ZhouServlet?msg=…)。
package com. itheima03. redirect ;
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ; @WebServlet ( urlPatterns
= "/ShiServlet" )
public class ShiServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { request
. setCharacterEncoding ( "utf-8" ) ; doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String msg
= request
. getParameter ( "msg" ) ; System . out
. println ( "shi:" + msg
) ; response
. setStatus ( 302 ) ; response
. setHeader ( "location" , "/ZhouServlet?msg=xx" ) ; }
}
package com. itheima03. redirect ;
import javax. servlet. ServletException ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. IOException ; @WebServlet ( urlPatterns
= "/ZhouServlet" )
public class ZhouServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String msg
= request
. getParameter ( "msg" ) ; System . out
. println ( "zhou:" + msg
) ; System . out
. println ( "这个哥们还不错" ) ; response
. setContentType ( "text/html;charset=utf-8" ) ; response
. getWriter ( ) . print ( "这个哥们还可以,大约3K" ) ; }
}
如下浏览器F12,第二行没有带参数,拿不到msg。 前面登陆成功请求转发到成功.html页面,失败.html…。用请求转发不合适,因为没有传递数据,应该用重定向。请求转发一次请求,地址指向第一次访问位置如下(网址阅读性太差,实际页面应该为localhost:8080/success.html)。 如下红框用重定向,登陆失败逻辑错误,之后再改。 如下重定向,第一次请求收到302。
12.文件下载:request/response
首先服务器要有文件,在网络编程做过文件上传。在servlet里写代码覆盖tomcat默认设置。
//02文件下载.html
< html lang = " en" >
< head> < meta charset = " UTF-8" > < title> Title
</ title>
</ head>
< body> < a href = " /DownloadServlet?file=1.zip" > 1.zip
</ a> < br> < a href = " /DownloadServlet?file=2.exe" > 2.exe
</ a> < br> < a href = " /DownloadServlet?file=3.txt" > 3.txt
</ a> < br> < a href = " /DownloadServlet?file=4.jpg" > 4.jpg
</ a> < br>
</ body>
</ html>
package com. itheima04. down ;
import javax. servlet. ServletContext ;
import javax. servlet. ServletException ;
import javax. servlet. ServletOutputStream ;
import javax. servlet. annotation. WebServlet ;
import javax. servlet. http. HttpServlet ;
import javax. servlet. http. HttpServletRequest ;
import javax. servlet. http. HttpServletResponse ;
import java. io. FileInputStream ;
import java. io. IOException ; @WebServlet ( urlPatterns
= "/DownloadServlet" )
public class DownloadServlet extends HttpServlet { @Override protected void doPost ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { doGet ( request
, response
) ; } @Override protected void doGet ( HttpServletRequest request
, HttpServletResponse response
) throws ServletException , IOException { String file
= request
. getParameter ( "file" ) ; response
. setHeader ( "content-disposition" , "attachment;filename=x" + file
) ;
ServletContext servletContext
= request
. getServletContext ( ) ; String realPath
= servletContext
. getRealPath ( "dir/" + file
) ; FileInputStream fis
= new FileInputStream ( realPath
) ; ServletOutputStream os
= response
. getOutputStream ( ) ; int length
; byte [ ] buffer
= new byte [ 1024 ] ; while ( ( length
= fis
. read ( buffer
) ) != - 1 ) { os
. write ( buffer
, 0 , length
) ; } fis
. close ( ) ; os
. close ( ) ; System . out
. println ( "文件下载完毕" ) ; }
}
响应体交给浏览器,浏览器自动下载。 linux没有盘符,所以不能用绝对路径,不好部署。如下artifacts指整个项目,运行的是如下蓝字编译的内容(黄色文件夹),只要获得web_war_exploded文件夹就能得到其他文件相对路径。用serlvetContext = web_war_exploded文件夹路径(exploded部署意思,如下红线),如下右边servletContext是生命周期最长的域对象,所以可以将数据传到服务器任何地方。
request除了作为域对象还有本职工作即获取请求数据,servletContext很像连接池(连接池一个就够),服务器没关,连接池不消毁。servletContext生命周期和web应用一样长,所以也叫application应用,环境参数如相对路径。request和session两个域对象用的最多,pageContext太短,servletContext太长。重定向不能通过request传递数据,可以用servletContext传递数据,但是一般也不这么做,servletContext占用内存大。 上图灰色WEB-INF文件夹中添加lib文件夹里放druid-1.0.9.jar包并右击add as library【Mysql3】,点乌龟运行tomcat后,会生成黄色lib文件夹。黄色classes文件夹里代码不能直接访问,需用web.xml或用注解建立映射关系访问:WEB-INF下是浏览器无法直接访问,通过建立映射,url访问,由tomcat访问。 热更新不做编译,新增类必须停下来。
与50位技术专家面对面 20年技术见证,附赠技术全景图
总结
以上是生活随笔 为你收集整理的【Java12】tomcatservlet(nginx,web.xml,生命周期,适配器优化),requestresponse(请求转发,登陆案例(1),重定向,文件下载) 的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔 网站内容还不错,欢迎将生活随笔 推荐给好友。