一、编码问题的原则
1. 英文字母不会出现乱码问题,所有的编码表都包含Unicode编码表
2. 字符流=字节流+编码表 使用tomcat服务器时,默认使用tomcat默认编码表
3. tomcat6.x tomcat7.x 默认全是ISO-8859-1 tomcat8.x默认使用UTF-8
4. 在jsp编程中,getByte();默认使用ANSI 本地的编码表GBK
5. getByte()中有带有编码表的构造,可以指定字符通过什么编码返回byte数组
二、HTTPServletResponse
1. getOutputStream和getWriter()不能同时使用
这两个流不需要我们手动释放,Servlet会自动释放
response.getOutputStream().write("中文乱码".getBytes());
response.getWriter().print("中文乱码");
2. 常用标头
a. 刷新 response.setHeader("Refresh", "1");一秒钟刷新一次
b. 设置指定时间重定向 response.setHeader("Refresh", "3;URL=/index.jsp");URL可以省略
è转发: / 代表当前应用
l 只有一次请求,共享请求
l 需要共享request时使用转发
l 地址栏不会变化
l 服务器的内部行为
l 只能转发内部地址
//通过得到上下文对象实现页面跳转 /代表当前项目中 不能使用相对路径
getServletContext().getRequestDispatcher("/index.jsp").forward(request, response);
//得到请求对象,实现页面跳转
request.getRequestDispatcher("/Test.html").forward(request, response);
è重定向: / 代表tomcat 根目录
l 会发出新的请求
l 地址栏会发生变化
l 可以转发内部地址,也可以访问外部资源
l 不写/代表 相对路径
//使用相对路径时指向的就是当前class路径
response.sendRedirect("myServlet_OutputStream");
response.setHeader("Refresh", "3;URL=当前类空间中的class文件 ");
c. 缓冲时间 response.setDateHeader("Expires",System.currenTimeMillis()+1*1000*60*60); /1 小时
地址栏直接Enter键 是使用缓存需要更新 需要刷新 才会更新页面
静态的web资源是可以缓存的
动态的web资源是不建议使用缓存的
控制没有缓冲
//控制没有缓存
response.setHeader("expires","0");
response.setHeader("cache-control","no-cache");
response.setHeader("pragma","no-cache");
3. 字节流乱码的解决办法
l 修改浏览解析编码
l 告诉浏览器,使用的是UTF-8,同时字节流输出的byte数组也为UTF-8(如下三种)
l 直接写出字符标签 response.getOutputStream().write();è不推荐使用
response.getOutputStream().write("<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\">".getBytes());
response.getOutputStream().write("中文乱码".getBytes("UTF-8"));
头标签在使用时,有的浏览器会直接识别为字符串显示出来
l 通过设置头标签 response.setHeader();
response.setHeader("Content-type", "text/html;charset=UTF-8");
response.getOutputStream().write("中文乱码".getBytes("UTF-8"));
l 直接设置标签内的值 response.setContentType(); è推荐使用
response.setContentType("text/html;charset=UTF-8");
response.getOutputStream().write("中文乱码".getBytes("UTF-8"));
4. 字符流乱码的解决办法
l 直接写出标签在字符流中不能使用,剩下的都可以使用,推荐如下!
response.setContentType("text/html;charset=UTF-8");
response.getWriter().print("中文乱码d");
三、HTTPServletRequest
1. 请求的方法
l java.lang.String getContextPath() 应用名称
l java.lang.String getMethod() 获取请求方式,获取的是大写
l java.lang.String getQueryStrin() 获取请求的数据
l java.lang.StringBufferget RequestURL() 当前项目的访问路径,推荐使用ServletContext的getRealPath替代
l java.lang.String getRequestURI() 获取不包括主机名端口号的访问路径
l getRealPath() 获取绝对路径
l getProtocol() 获取协议和版本
l getRemoteAddr() 获取来访者的IP地址
2. 获取表单数据(最常用的方法)
l 根据表单的name获取表单的value request.getParameter(""); 获取单个value
l 根据表单的name获取表单的value数组 request.getParameterValues("") 一般用于checkbox和radio
l 获取表单中的所有的name request.getParameterNames();
l 获取重复的表单name 只能获取到检索到的第一个value
l checkbox和radio如果不选择,客户端不发送数据到服务器
3. 获取数据的內省机制(反射原理)
User user = new User(); //表单提交了多少数据过来? Enumeration<String> e = request.getParameterNames(); while(e.hasMoreElements()) { //获取每一个表单的name String fieldName = e.nextElement(); String fieldValue = request.getParameter(fieldName); try { //内省 PropertyDescriptor pd = new PropertyDescriptor(fieldName,User.class); Method m = pd.getWriteMethod();//得到指定字段的set方法 m.invoke(user, fieldValue); } catch (Exception e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } |
4. 一种简单的对象封装方法(使用Apache的开源类库)
BeanUtils.populate(user, request.getParameterMap());
import org.apache.commons.beanutils.BeanUtils;
可以自动得到Key和value并封装到给定的对象之中,原理是內省
5. 中文乱码问题
post方式:request.setCharacterEncoding("UTF-8"); 获取数据前
get方式: username=new String(username.getBytes("ISO-8859-1"),"UTF-8");使用打回原形的方式
原因:get是直接在地址栏传递的,请求前已经编码过,默认认为中文是不安全的,默认ISO-8859-1
所以需要打回原形实现码
使用getInpuStream()时必须使用post,用于文件的上传!
6. 跳转和包含
//跳转request.getRequestDispatcher("/register.html").forward(request, response);
//包含request.getRequestDispatcher("/register.html").include(request, response);