目录
2-3-3 表单提交到一个servlet(RegistServlet)
2-3-6 userdao 通过dbutils在数据库中插入一条记录
习目标:会使用request和response
-
一、案例1-文件下载案例
技术分析:
response
文件下载
-
1-1 response:响应
作用:
往浏览器写东西
组成部分:
响应行 响应头 响应体
-
1-1-1 操作响应行
1.格式:
协议/版本 状态码 状态码说明 HTTP/1.1 200 OK
2.状态码:
1xx:已发送请求
2xx:已完成响应
200:正常响应
3xx:还需浏览器进一步操作
302:重定向 配合响应头:location
304:读缓存
4xx:用户操作错误
404:用户操作错误.
405:访问的方法不存在
5xx:服务器错误
500:内部异常
3.常用方法:
setStatus(int 状态码):针对于 1 2 3
了解 sendError(int 状态码):针对于 4xx和5xx
-
1-1-2 操作响应头 重定向、定时刷新
1.格式:key/value(value可以是多个值)
2.常用的方法:在Interface HttpServletResponse(java_ee_api),由Tomcat实现
setHeader(String key,String value):设置字符串形式的响应头
了解:setIntHeader(String key,int value):设值整形的响应头
了解:setDateHeader(String key,long value):设值时间的响应头
addHeader(String key,String value):添加置字符串形式的响应头 之前设置过则追加,若没有设置过则设置
了解:addIntHeader(String key,int value):添加整形的响应头
了解:addDateHeader(String key,long value):添加时间的响应头
3.常用的响应头:
location:重定向
refresh:定时刷新
content-type:设置文件的mime类型,设置响应流的编码及告诉浏览器用什么编码打开
content-disposition:文件下载
- 重定向:
方式1:
★response.sendRedirect("/day10/loc2");
方式2:
response.setStatus(302);
respooen.setHeader("location","/day10/loc2");/** * 重定向 */ public class Loc1Servlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("我说:没零钱~~"); System.out.println("又曰:找侯老师"); //方式2:理解 //设状态码 302 //response.setStatus(302); //设置响应头 //response.setHeader("location", "/day10/loc2"); //方式1:掌握 response.sendRedirect("/day10/loc2"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
/** * 侯老师 */ public class Loc2Servlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("老侯曰:给你20"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
- 定时刷新:
方案1:设置头 refresh 昨天做过
respooen.setHeader("refresh","秒数;url=跳转的路径");
方案2:http的meta标签http-equiv:响应头
content:响应头的内容
<meta http-equiv="refresh" content="3;url=/day10/refresh2.html">
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <!-- http-equiv:响应头 content:响应头的内容 --> <meta http-equiv="refresh" content="3;url=/day10/refresh2.html"> <title>Insert title here</title> </head> <body> XXXX成功了,<span id="sid">3</span>秒之后跳转到refresh2.html上. </body> <script type="text/javascript"> onload=function(){ //设置定时器 setInterval(changeS, 1000); } i=3; //时间变化 function changeS(){ //1.获取元素 var obj=document.getElementById("sid"); //2.操作元素的标签体 obj.innerHTML=--i; } </script> </html>
-
1-1-3 操作响应体
页面上要展示的内容
1.常用方法:
Writer getWriter():字符流
ServletOutputStream getOutputStream() :字节流
自己写的东西用字符流,其他一概用字节流.
2.处理响应中文乱码:
方式1:★
response.setContentType("text/html;charset=utf-8");
方式2:理解
response.setHeader("content-type", "text/html;charset=utf-8");/** * 操作响应体 */ public class PrintSerlvet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //处理响应的中文乱码 response.setContentType("text/html;charset=utf-8"); //response.setHeader("content-type", "text/html;charset=utf-8"); //ServletOutputStream os = response.getOutputStream(); //打印表格 //获取字符流 PrintWriter w = response.getWriter(); w.print("<table border='1'><tr>"); w.print("<td>用户名:</td>"); w.print("<td>tom</td></tr>"); w.print("<tr><td>密码:</td>"); w.print("<td>123</td>"); w.print("</tr></table>"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
注意:
两个流互斥
当响应完成之后,服务器会判断一下流是否已经关闭,若没有关闭,服务器会帮我们关闭.(底层使用的缓冲流)
-
1-2 文件下载
-
1-2-1 下载方式
1.超链接下载
<a href="/day10/download/day10.txt">下载 day10.txt</a>——资源存放在 WebContent/download 目录下
若浏览器能解析该资源的mime类型,则打开;若不能接下则下载;
2.编码下载 通过servlet完成——servlet要设置路径
<servlet> <description></description> <display-name>DownloadServlet</display-name> <servlet-name>DownloadServlet</servlet-name> <servlet-class>com.itheima.a_response.c_download.DownloadServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>DownloadServlet</servlet-name> <url-pattern>/download</url-pattern> </servlet-mapping>
<a href="/day10/download?name=day10.txt">下载 day10.txt</a>
a.设置文件的mime类型
String mimeType=context.getMimeType(文件名)
response.setContentType(mimeType);
b.设置下载头信息 content-disposition
response.setHeader("content-disposition", "attachment;filename="+文件名称);
c.提供流//获取输入流 /到WebContent目录
InputStream is = context.getResourceAsStream("/download/"+filename);//获取输出流
ServletOutputStream os = response.getOutputStream();扩展:使用commons-io工具类导入 commons-io.jar 包
对拷流:
IOUtils.copy(is,os);/** * 文件下载 */ public class DownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取下载文件的名称 String filename = request.getParameter("name"); //注意中文乱码: filename=new String(filename.getBytes("iso8859-1"),"utf-8"); ServletContext context = this.getServletContext(); //文件下载 //1.设置文件的mimeType String mimeType = context.getMimeType(filename); response.setContentType(mimeType); //2.设置下载的头信息 response.setHeader("content-disposition", "attchment;filename="+filename); //3.对拷流 //获取输入流 /到WebContent目录 InputStream is = context.getResourceAsStream("/download/"+filename); //获取输出流 ServletOutputStream os = response.getOutputStream(); /*int len=-1; byte[] b=new byte[1024]; while((len=is.read(b))!=-1){ os.write(b, 0, len); }*/ //对拷流 IOUtils.copy(is, os); os.close(); is.close();//必须要关流 } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
1-3 扩展 通过response生成验证码
通过response生成验证码
验证码:
作用:防止暴力攻击
点击换一张的js代码:
function changeImg(obj){
//操作src属性
obj.src="/day10/code?i="+Math.random();
//alert(1)
}html页面
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <img alt="验证码" src="/day10/code" title="看不清除,换一张" onclick="changeImg(this)"> </body> <script type="text/javascript"> function changeImg(obj){ //操作src属性 obj.src="/day10/code?i="+Math.random(); //obj.src="/day10/code"; //alert(1) } </script> </html>
验证码servlet
public class CodeServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 使用java图形界面技术绘制一张图片 int charNum = 4; int width = 30 * 4; int height = 30; // 1. 创建一张内存图片 BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 2.获得绘图对象 Graphics graphics = bufferedImage.getGraphics(); // 3、绘制背景颜色 graphics.setColor(Color.YELLOW); graphics.fillRect(0, 0, width, height); // 4、绘制图片边框 graphics.setColor(Color.BLUE); graphics.drawRect(0, 0, width - 1, height - 1); // 5、输出验证码内容 graphics.setColor(Color.RED); graphics.setFont(new Font("宋体", Font.BOLD, 20)); // 随机输出4个字符 Graphics2D graphics2d = (Graphics2D) graphics; String s = "ABCDEFGHGKLMNPQRSTUVWXYZ23456789"; Random random = new Random(); // session中要用到 String msg = ""; int x = 5; for (int i = 0; i < 4; i++) { int index = random.nextInt(32); String content = String.valueOf(s.charAt(index)); msg += content; double theta = random.nextInt(45) * Math.PI / 180; // 让字体扭曲 graphics2d.rotate(theta, x, 18); graphics2d.drawString(content, x, 18); graphics2d.rotate(-theta, x, 18); x += 30; } // 6、绘制干扰线 graphics.setColor(Color.GRAY); for (int i = 0; i < 5; i++) { int x1 = random.nextInt(width); int x2 = random.nextInt(width); int y1 = random.nextInt(height); int y2 = random.nextInt(height); graphics.drawLine(x1, y1, x2, y2); } // 释放资源 graphics.dispose(); // 图片输出 ImageIO ImageIO.write(bufferedImage, "jpg", response.getOutputStream()); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
-
二、案例2-完成用户注册操作
需求:
在一个表单页面上填写用户数据,点击提交,将所有的数据提交的服务器上,通过java代码最终保存到数据库中.
技术分析:
表单
request
-
2-1 request:请求
作用:获取浏览器发送过来的数据
组成部分:
请求行 请求头 请求体
-
2-1-1 操作请求行
1.格式:
请求方式 请求资源 协议/版本 GET /day0801/1.html HTTP/1.1
2.常用方法:HttpServletRequest
掌握
String getMethod():获取请求方式——例如 GET、POST 或 PUT
String getRemoteAddr():获取ip地址
String getContextPath() :在java中获取项目名称 (/day10)
了解:
getRequestURI():获取的是 从项目名到参数之前的内容 /day10/regist
getRequestURL():获取的带协议的完整路径 http://localhost/day10/regist
String getQueryString():get请求的所有参数 username=tom&password=123
String getProtocol():获取协议和版本
3.例如:请求行
GET /day10/row?username=tom&password=123 HTTP/1.1/* 操作请求行 例如:GET /day10/row?username=tom&password=123 HTTP/1.1 */ public class RowServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取 请求方式 ————GET String m=request.getMethod(); System.out.println("方式:"+m); //获取请求资源 //uri:/day10/row //url:http://localhost/day10/row String uri = request.getRequestURI(); String url = request.getRequestURL().toString(); System.out.println("uri:"+uri); System.out.println("url:"+url); //获取请求参数的字符串 ————username=tom&password=123 String s = request.getQueryString(); System.out.println("get请求参数:"+s); //获取协议版本 ————HTTP/1.1 String p = request.getProtocol(); System.out.println("协议:"+p); System.out.println("-------重要的----"); //获取请求的ip ————0:0:0:0:0:0:0:1 String ip = request.getRemoteAddr(); System.out.println("ip:"+ip); //获取项目名 ————/day10 String path = request.getContextPath(); System.out.println("项目路径:"+path); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
2-1-2 操作请求头
1.格式:key/value(value可以是多个值)
2.常用方法:
★String getHeader(String key):通过key获取指定的value (一个)
了解:
Enumeration getHeaders(String name) :通过key获取指定的value(多个)
Enumeration getHeaderNames() :获取所有的请求头的名称
int getIntHeader(String key):获取整型的请求头
long getDateHeader(String key):获取时间的请求头
3.重要的请求头:
user-agent:浏览器内核 msie firefox chrome String agent = request.getHeader("user-agent");referer:页面从那里来 防盗链 String referer = request.getHeader("referer");
/** * 操作请求头 */ public class HeaderServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取浏览器内核 String agent = request.getHeader("user-agent"); System.out.println(agent); //获取referer String referer = request.getHeader("referer"); if(referer==null){ System.out.println("直接在地址栏上输入的"); }else if(referer.contains("localhost")){ System.out.println("我自己点的.."); }else if(referer.contains("192.168.")){ System.out.println("哥们儿姐们儿点的"); }else{ System.out.println("盗链者可耻"); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
2-1-3 操作请求参数 ★
- username=tom&password=123&hobby=drink&hobby=sleep
1.常用方法:
String getParameter(String key):获取一个值
String[] getParameterValues(String key):通过一个key获取多个值
Map<String,String[]> getParameterMap():获取所有的参数名称和值
/** * 获取请求参数 */ public class ParamServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取username String username = request.getParameter("username"); System.out.println("username:"+username); //获取爱好 多个值 String[] hobby = request.getParameterValues("hobby"); System.out.println("hobby:"+Arrays.toString(hobby)); //获取所有 System.out.println("============"); Map<String, String[]> map = request.getParameterMap(); for(String key:map.keySet()){ System.out.println(key+"::"+Arrays.toString(map.get(key))); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
username:tom
---------values---------
hobby:[drink, sleep]
=====map=======
username::[tom]
password::[123]
hobby::[drink, sleep]
-
2-1-4 请求的中文乱码
对于get请求:参数追加到地址栏,会使用utf-8编码,服务器(tomcat7)接受到请求之后,使用iso-8859-1解码,所以会出现乱码
对于post请求,参数是放在请求体中,服务器获取请求体的时候使用iso-8859-1解码,也会出现乱码
1.通用的方法:
new String(参数.getBytes("iso-8859-1"),"utf-8");——单个设置
2.针对于post请求来说:只需要将请求流的编码设置成utf-8即可——全部设置,——get不行
request.setCharacterEncoding("utf-8");
/** 获取请求参数 */ public class Param_Servlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //设置编码 request.setCharacterEncoding("utf-8"); //获取用户名和密码: String username = request.getParameter("username"); String password = request.getParameter("password"); //username=new String(username.getBytes("iso8859-1"),"utf-8"); System.out.println(username+"::"+password); } }
-
2-2 域对象 request 请求转发(请求链,请求串)
request:
创建:一次请求来的时候
销毁:响应生成的时候
作用:
一次请求里面的数据
请求转发(请求链,请求串)
request.getRequestDispatcher("内部路径").forward(request,response); 内部路径:在xml中配置 的路径/** * 请求转发 */ public class Dis1Servlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("我说:稍等"); //将借钱人的姓名放入reuqest中 request.setAttribute("username", "++"); //请求转发 内部路径:在xml中配置 的路径 request.getRequestDispatcher("/dis2").forward(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
/** * 侯老师 */ public class Dis2Servlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("侯老师曰:需要多少? 我答:"+request.getParameter("money")); System.out.println("侯老师又曰:干嘛用啊? 我答:借给"+request.getAttribute("username")); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
-
2-3 案例2-步骤分析
-
2-3-1 数据库和表(day09)
-
2-3-2 页面(表单)
给每个字段添加name属性——input中设置name属性
还需修改表单提交的路径 method=post<form class="form-horizontal" style="margin-top:5px;" action="/day1001/regist" method="post"> <div class="form-group"> <label for="username" class="col-sm-2 control-label">用户名</label> <div class="col-sm-6"> <input type="text" class="form-control" id="username" placeholder="请输入用户名" name="username"> </div> </div> <div class="form-group"> <label for="inputPassword3" class="col-sm-2 control-label">密码</label> <div class="col-sm-6"> <input type="password" class="form-control" id="inputPassword3" placeholder="请输入密码" name="password"> </div> </div> <div class="form-group"> <label for="confirmpwd" class="col-sm-2 control-label">确认密码</label> <div class="col-sm-6"> <input type="password" class="form-control" id="confirmpwd" placeholder="请输入确认密码"> </div> </div> <div class="form-group"> <label for="inputEmail3" class="col-sm-2 control-label">Email</label> <div class="col-sm-6"> <input type="email" class="form-control" id="inputEmail3" placeholder="Email" name="email"> </div> </div> <div class="form-group"> <label for="usercaption" class="col-sm-2 control-label">姓名</label> <div class="col-sm-6"> <input type="text" class="form-control" id="usercaption" placeholder="请输入姓名" name="name"> </div> </div> <div class="form-group opt"> <label for="inlineRadio1" class="col-sm-2 control-label">性别</label> <div class="col-sm-6"> <label class="radio-inline"> <input type="radio" name="sex" id="inlineRadio1" value="男"> 男 </label> <label class="radio-inline"> <input type="radio" name="sex" id="inlineRadio2" value="女"> 女 </label> </div> </div> <div class="form-group"> <label for="date" class="col-sm-2 control-label">出生日期</label> <div class="col-sm-6"> <input type="date" class="form-control" name="birthday"> </div> </div> <div class="form-group"> <label for="date" class="col-sm-2 control-label">验证码</label> <div class="col-sm-3"> <input type="text" class="form-control" > </div> <div class="col-sm-2"> <img src="./image/captcha.jhtml"/> </div> </div> <div class="form-group"> <div class="col-sm-offset-2 col-sm-10"> <input type="submit" width="100" value="注册" name="submit" border="0" style="background: url('./images/register.gif') no-repeat scroll 0 0 rgba(0, 0, 0, 0); height:35px;width:100px;color:white;"> </div> </div> </form>
-
2-3-3 表单提交到一个servlet(RegistServlet)
配置路径
<servlet> <description></description> <display-name>RegistServlet</display-name> <servlet-name>RegistServlet</servlet-name> <servlet-class>com.itheima.web.servlet.RegistServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>RegistServlet</servlet-name> <url-pattern>/regist</url-pattern> </servlet-mapping>
-
2-3-4 RegistServlet
操作:
接受数据,封装成一个userprivate int id; private String username; private String password; private String email; private String name; private String sex; private String birthday; private String hobby;
调用UserSerivce完成保存操作 int regist(User user)
判断结果是否符合我们预期
若int=1; 插入成功
若int !=1 ; 插入失败
相应的提示信息在当前的servlet不做处理,将信息转发给另一个servlet展示(MsgServlet);RegistServlet 实现
/** * 用户注册 */ public class RegistServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //0.设置编码 request.setCharacterEncoding("utf-8"); //1.封装数据 //创建一个user 调用user.setXxx()一个个封装不推荐 //使用beanutils封装对象 User user=new User(); try { BeanUtils.populate(user, request.getParameterMap()); //2.调用userserivce . regist(user) 返回值:int int i=new UserService().regist(user); //3.判断int 将信息请求转发到msgservlet if(i==1){ //展示信息 request.setAttribute("msg", "添加成功"); request.getRequestDispatcher("/msg").forward(request, response); }else{ request.setAttribute("msg", "添加失败"); request.getRequestDispatcher("/msg").forward(request, response); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
MsgServlet 实现
/** * 展示信息 */ public class MsgServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //0.设置编码 response.setContentType("text/html;charset=utf-8"); //1.从request域中获取内容 msg String s=(String) request.getAttribute("msg"); //2.将信息打印到页面上 response.getWriter().print(s); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
-
2-3-5 UserService
调用dao
/** * 用户注册 * @param user 用户 * @return * @throws SQLException */ public int regist(User user) throws SQLException { //调用dao UserDao dao=new UserDao(); return dao.addUser(user); }
-
2-3-6 userdao 通过dbutils在数据库中插入一条记录
/** * 添加用户 * @param user 用户信息 * @return * @throws SQLException */ public int addUser(User user) throws SQLException { QueryRunner qr=new QueryRunner(DataSourceUtils.getDataSource()); /** * id int primary key auto_increment, username varchar(20), password varchar(20), email varchar(20), name varchar(20), sex varchar(10), birthday date, hobby varchar */ String sql="insert into user(username,password,email,name,sex,birthday,hobby) values (?,?,?,?,?,?,?)"; return qr.update(sql, user.getUsername(),user.getPassword(),user.getEmail(), user.getName(),user.getSex(),user.getBirthday(),user.getHobby()); }
-
2-4 封装对象BeanUtils
apache提供的一个工具类
BeanUtils
封装数据
使用步骤:
1.导入jar包:commons-beanutils-1.8.3.jar 和 commons-logging-1.1.1.jar
2.调用 BeanUtils.populate(Object bean,Map<> 参数); BeanUtils.populate(user, request.getParameterMap());//1.封装数据 //创建一个user 调用user.setXxx()一个个封装不推荐 //使用beanutils封装对象 User user=new User(); try { BeanUtils.populate(user, request.getParameterMap()); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(); }
-
2-5 请求转发和重定向区别
重定向发送两次请求,请求转发一次请求
重定向地址栏发生改变,请求转发不变
重定向是从浏览器发送,请求转发是服务器内部
重定向不存在request域对象,请求转发可以使用request域对
重定向是response的方法,请求转发是request的方法
重定向可以请求站外资源,请求转发不可以
-
2-6 扩展指定编码和解码
URLEncoder.encode(s, "utf-8"); 指定编码
URLDecoder.decode(s8, "iso8859-1");指定解码
public class EncodeDemo { public static void main(String[] args) throws Exception { String s="黑马"; String s8=URLEncoder.encode(s, "utf-8"); //System.out.println(s8);————%E9%E9%E9%E9%E9等等 String so = URLDecoder.decode(s8, "iso8859-1"); System.out.println(so);//————出现乱码 byte[] b = so.getBytes("iso-8859-1");//逆回去 String _s = new String(b, "utf-8");//再设置解码 System.out.println(_s); } }
-
2-7 文件下载扩展
中文名称的文件名下载的时候名称会出现问题
常见的浏览器需要提供文件名称的utf-8编码
对于火狐来说需要提供文件名称的base64编码
方案1:使用工具类
public class DownLoadUtils { public static String getName(String agent, String filename) throws UnsupportedEncodingException { if (agent.contains("MSIE")) { // IE浏览器 filename = URLEncoder.encode(filename, "utf-8"); filename = filename.replace("+", " "); } else if (agent.contains("Firefox")) { // 火狐浏览器 BASE64Encoder base64Encoder = new BASE64Encoder(); filename = "=?utf-8?B?" + base64Encoder.encode(filename.getBytes("utf-8")) + "?="; } else { // 其它浏览器 filename = URLEncoder.encode(filename, "utf-8"); } return filename; } }
方案2:网上的方式(8成好使)
new String(filename.getByte("gbk"),"iso8859-1");
//2.设置下载的头信息 //上午的————中文出现乱码 //response.setHeader("content-disposition", "attchment;filename="+filename); //常见的浏览器将文件名称使用utf-8 不推荐 不兼容火狐 //response.setHeader("content-disposition", "attchment;filename="+URLEncoder.encode(filename, "utf-8")); //方式1:通过的方式 通过工具类编码 String _filename=DownLoadUtils.getName(request.getHeader("user-agent"), filename); response.setHeader("content-disposition", "attachment;filename="+_filename); //方式2:网络上的方式 (8成好使) //response.setHeader("content-disposition", "attachment;filename="+new String(filename.getBytes("gbk"),"iso8859-1"));
-
总结
- 1.response:
操作响应行
状态码
常用方法:
setStatus(int code) 针对的1xx 2xx 3xx
操作响应头:
setHeader(String key,String value):设置
addHeader(String key,String value):添加
常用的响应头:
location:重定向:
response.sendRedirect("跳转路径");
refresh:定时刷新
response.setHeader("refresh","秒数;url=路径");//java
meta标签//html代码
content-type:设置文件的mimeType,及设置响应流的编码并且通知浏览器用什么编码打开
response.setContentType("text/html;charset=utf-8");
content-disposition:设置文件下载
response.setHeader("content-disposition","attachment;filename="+文件名称);
操作响应体
getWriter():
getOutputStream():
注意:俩流互斥,服务器帮我们关闭此流
响应的中文乱码:
response.setContentType("text/html;charset=utf-8");
- 2.文件下载:
1.超链接下载
2.编码下载(两个头一个流)
设置文件的mimetype
设置下载头信息
对拷流
扩展:
文件名称中文问题:
方法1:
firefox :base64
其他:utf-8
方法2:(八九成可以使用)
new String(filename.getBytes("gbk"),"iso8859-1");
- 3.request:请求 获取浏览器发送过来的数据
操作请求行
getMethod():请求方式
getContextPath():获取项目名称
getRemoteAddr():获取请求的ip地址
操作请求头
String getHeader(String key)
常见的头信息:
user-agent:获取浏览器内核
referer:页面从那里跳转过来的
操作请求参数
String getParameter(String key):
String[] getParameterValues(String key):
Map<String ,String[]> getParameterMap();
请求的中文乱码:
对于get请求:参数追加到地址栏,会使用utf-8编码,服务器(tomcat7)接受到请求之后,使用iso-8859-1解码,所以会出现乱码
对于post请求,参数是放在请求体中,服务器获取请求体的时候使用iso-8859-1解码,也会出现乱码
通用的方法:
new String(参数.getBytes("iso-8859-1"),"utf-8");
针对于post请求来说:只需要将请求流的编码设置成utf-8即可
request.setCharacterEncoding("utf-8");
域对象:request
请求转发:
request.getRequestDispatcher("内部路径").forward(request,response);
request生命周期:
一次请求
- 4.扩展:封装数据:
apache的BeanUtils
1.导入两个jar包
2.调用 BeanUtils.populate(Object bean,map);