1、如何解决 tomcat 中文乱码问题?

2、如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。

 <!-- 将ServletDemo2配置成缺省Servlet -->
<servlet-mapping>
<servlet-name>ServletDemo2</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

3、Servlet 线程安全:当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。

3.1通过ServletContext获取web资源的绝对路径

String path = this.getServletContext().getRealPath("/WEB-INF/classes/db/config/db3.properties");

4、ServletContext对象

WEB容器在启动时,它会为每个WEB应用程序都创建一个对应的ServletContext对象,它代表当前web应用。
  ServletConfig对象中维护了ServletContext对象的引用,开发人员在编写servlet时,可以通过ServletConfig.getServletContext方法获得ServletContext对象。
  由于同一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象来实现通讯。ServletContext对象通常也被称之为context域对象。


ServletContext context = this.getServletConfig().getServletContext();//获得ServletContext对象
context.setAttribute("data", data); //将data存储到ServletContext对象
在另一个 servlet 中:

String data = (String) context.getAttribute("data");//从ServletContext对象中取出数据

5、获取WEB应用的初始化参数

在web.xml文件中使用<context-param>标签配置WEB应用的初始化参数
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name></display-name>
<!-- 配置WEB应用的初始化参数 -->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</context-param>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

servlet 中 获取Web应用的初始化参数:


ServletContext context = this.getServletContext();
//获取整个web站点的初始化参数
String contextInitParam = context.getInitParameter("url");

6、页面跳转  用servletContext实现请求转发

(6.1)Request对象实现请求转发

        A、通过 ServletContext 的 getRequestDispatcher(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。


ServletContext context = this.getServletContext();//获取ServletContext对象
RequestDispatcher rd = context.getRequestDispatcher("/servlet/ServletContextDemo5");//获取请求转发对象(RequestDispatcher)
rd.forward(request, response);//调用forward方法实现请求转发
 
RequestDispatcher reqDispatcher =this.getServletContext().getRequestDispatcher("/test.jsp");
reqDispatcher.forward(request, response);

B:2、通过request 对象提供的 getRequestDispatche(String path)方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。

request.getRequestDispatcher("/test.jsp").forward(request, response);
<body>
使用普通方式取出存储在request对象中的数据:
<h3 style="color:red;"><%=(String)request.getAttribute("data")%></h3>
使用EL表达式取出存储在request对象中的数据:
<h3 style="color:red;">${data}</h3>
</body>

2、通过response实现请求重定向

 /**
* 1.调用sendRedirect方法实现请求重定向,
* sendRedirect方法内部调用了
* response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
* response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);
*/
response.sendRedirect("/JavaWeb_HttpServletResponse_Study_20140615/index.jsp"); //2.使用response设置302状态码和设置location响应头实现重定向实现请求重定向
//response.setHeader("Location", "/JavaWeb_HttpServletResponse_Study_20140615/index.jsp");
//response.setStatus(HttpServletResponse.SC_FOUND);//设置302状态码,等同于response.setStatus(302);

7、利用ServletContext对象读取资源文件

注意:通过类装载器读取资源文件的注意事项:不适合装载大文件,否则会导致jvm内存溢出
(1.1)使用类装载器读取资源文件【用类装载器读取src目录下的db1.properties配置文件】
  private void readPropFile(HttpServletResponse response) throws IOException {
//获取到装载当前类的类装载器
ClassLoader loader = ServletContextDemo7.class.getClassLoader();
//用类装载器读取src目录下的db1.properties配置文件
InputStream in = loader.getResourceAsStream("db1.properties");
Properties prop = new Properties();
prop.load(in);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
response.getWriter().println("用类装载器读取src目录下的db1.properties配置文件:");
response.getWriter().println(
MessageFormat.format(
"driver={0},url={1},username={2},password={3}",
driver,url, username, password));
}

(1.2)读取类路径下面、包下面的资源文件

//获取到装载当前类的类装载器
ClassLoader loader = ServletContextDemo7.class.getClassLoader();
//用类装载器读取src目录下的gacl.servlet.study包中的db4.properties配置文件
InputStream in = loader.getResourceAsStream("gacl/servlet/study/db4.properties");
Properties prop = new Properties();
prop.load(in);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
response.getWriter().println("用类装载器读取src目录下的gacl.servlet.study包中的db4.properties配置文件:");
response.getWriter().println(
MessageFormat.format(
"driver={0},url={1},username={2},password={3}",
driver,url, username, password));
}
(2)//读取src目录下的db.config包中的配置文件
 /**
* 通过ServletContext对象读取src目录下的properties配置文件
* @param response
* @throws IOException
*/
private void readSrcDirPropCfgFile(HttpServletResponse response) throws IOException {
/**
* 通过ServletContext对象读取src目录下的db1.properties配置文件
*/
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db1.properties");
Properties prop = new Properties();
prop.load(in);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
response.getWriter().println("读取src目录下的db1.properties配置文件:");
response.getWriter().println(
MessageFormat.format(
"driver={0},url={1},username={2},password={3}",
driver,url, username, password));
}
(3)读取 src 下某个包中的配置文件【读取src目录下的gacl.servlet.study包中的db4.properties配置文件】
private void readPropCfgFile2(HttpServletResponse response)
throws IOException {
InputStream in = this.getServletContext().getResourceAsStream("/WEB-INF/classes/gacl/servlet/study/db4.properties");
Properties prop = new Properties();
prop.load(in);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
response.getWriter().println("读取src目录下的gacl.servlet.study包中的db4.properties配置文件:");
response.getWriter().println(
MessageFormat.format(
"driver={0},url={1},username={2},password={3}",
driver,url, username, password));
}

(4)读取src目录下的db.config包中的db3.properties配置文件

//通过ServletContext获取web资源的绝对路径
String path = this.getServletContext().getRealPath("/WEB-INF/classes/db/config/db3.properties");
InputStream in = new FileInputStream(path);
Properties prop = new Properties();
prop.load(in);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
response.getWriter().println("读取src目录下的db.config包中的db3.properties配置文件:");
response.getWriter().println(
MessageFormat.format(
"driver={0},url={1},username={2},password={3}",
driver,url, username, password));
}

(5)通过ServletContext对象读取WebRoot目录下的properties配置文件

 /**
         * 通过ServletContext对象读取WebRoot目录下的properties配置文件
         * “/”代表的是项目根目录
         */
InputStream in = this.getServletContext().getResourceAsStream("/db2.properties");
Properties prop = new Properties();
prop.load(in);
String driver = prop.getProperty("driver");
String url = prop.getProperty("url");
String username = prop.getProperty("username");
String password = prop.getProperty("password");
response.getWriter().println("读取WebRoot目录下的db2.properties配置文件:");
response.getWriter().print(
MessageFormat.format(
"driver={0},url={1},username={2},password={3}",
driver,url, username, password));
}

8、向浏览器输出中文数据

(1)response.getOutputStream() :得到输出 二进制数据 的 ServletOuputStream对象。

(2)response.getWriter()方法:得到、输出文本数据 的 Printwriter对象。

(3)getOutputStream 和 getWriter这两个方法 互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。

(4)Servlet 程序向 ServletOutputStream 或 PrintWriter 对象中写入的数据将被Servlet引擎从 response 里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。

(5)Serlvet 的 service方法结束后,Servlet引擎将检查 getWriter 或 getOutputStream 方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象。

(8.1)以浏览器输出 binary data,字节流方式,需使用  OutputStream 流

在服务器端,数据是以哪个码表输出的,那么就要控制客户端浏览器以相应的码表打开。

比如:outputStream.write("中国".getBytes("UTF-8"));其意思是:使用OutputStream流向客户端浏览器输出中文,以UTF-8的编码进行输出;此时就要控制客户端浏览器以UTF-8的编码打开,否则显示的时候就会出现中文乱码。

那么在服务器端如何控制客户端浏览器以以UTF-8的编码显示数据呢?

(1)可以通过设置响应头控制浏览器的行为,例如:response.setHeader("content-type", "text/html;charset=UTF-8");其意思是:通过设置响应头控制浏览器以UTF-8的编码显示数据。

String data = "中国";
OutputStream outputStream = response.getOutputStream();//获取OutputStream输出流
//通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
response.setHeader("content-type", "text/html;charset=UTF-8");
byte[] dataByteArr = data.getBytes("UTF-8");//将字符转换成字节数组,指定以UTF-8编码进行转换
/**
* data.getBytes()是一个将字符转换成字节数组的过程,这个过程中一定会去查码表,
* 如果是中文的操作系统环境,默认就是查找查GB2312的码表,
* 将字符转换成字节数组的过程就是将中文字符转换成GB2312的码表上对应的数字
* 比如: "中"在GB2312的码表上对应的数字是98
* "国"在GB2312的码表上对应的数字是99
*/
/**
//getBytes()方法如果不带参数,那么就会根据操作系统的语言环境来选择转换码表,如果是中文操作系统,那么就使用GB2312的码表
outputStream.write(dataByteArr);//使用OutputStream流向客户端输出字节数组

(8.2)使用PrintWriter流向客户端浏览器输出中文数据,字符流方式, character text

      使用PrintWriter流输出中文注意问题:

  在获取PrintWriter输出流之前 首先使用 "response.setCharacterEncoding(charset)" 设置字符以什么样的编码输出到浏览器,

如:response.setCharacterEncoding("UTF-8");设置将字符以"UTF-8"编码输出到客户端浏览器,

然后再使用 response.getWriter(); 获取PrintWriter输出流,这两个步骤不能颠倒,如下:

response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
/**
* PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后
* 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码
*/
PrintWriter out = response.getWriter();//获取PrintWriter输出流

然后再使用 response.setHeader("content-type", "text/html;charset=字符编码");设置响应头,控制浏览器以指定的字符编码编码进行显示,例如:

response.setHeader("content-type", "text/html;charset=UTF-8");
//通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
/**
* 多学一招:使用HTML语言里面的<meta>标签来控制浏览器行为,模拟通过设置响应头控制浏览器行为
*response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
* 等同于response.setHeader("content-type", "text/html;charset=UTF-8");
*/
response.getWriter().write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");

具体实例:

public void outputChineseByPrintWriter(HttpServletResponse response) throws IOException{
String data = "中国"; //通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
//response.setHeader("content-type", "text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
/**
* PrintWriter out = response.getWriter();这句代码必须放在response.setCharacterEncoding("UTF-8");之后
* 否则response.setCharacterEncoding("UTF-8")这行代码的设置将无效,浏览器显示的时候还是乱码
*/
PrintWriter out = response.getWriter();//获取PrintWriter输出流
/**
* 多学一招:使用HTML语言里面的<meta>标签来控制浏览器行为,模拟通过设置响应头控制浏览器行为
* out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
* 等同于response.setHeader("content-type", "text/html;charset=UTF-8");
*/
out.write("<meta http-equiv='content-type' content='text/html;charset=UTF-8'/>");
out.write(data);//使用PrintWriter流向客户端输出字符
} public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}

9、response 文件下载

文件下载功能是web开发中经常使用到的功能,使用HttpServletResponse对象就可以实现文件的下载

文件下载功能的实现思路:

  1.   获取要下载的文件的绝对路径
  2.   获取要下载的文件名
  3.   设置 content-disposition 响应头控制浏览器以下载的形式打开文件
  4.   获取要下载的文件输入流
  5.   创建数据缓冲区
  6.   通过 response 对象获取 OutputStream 流
  7.   将 FileInputStream 流写入到 buffer 缓冲区
  8.   使用 OutputStream 将缓冲区的数据输出到客户端浏览器
    /**
    * 下载文件,通过OutputStream流
    * @param response
    * @throws FileNotFoundException
    * @throws IOException
    */
    private void downloadFileByOutputStream(HttpServletResponse response)
    throws FileNotFoundException, IOException {
    //1.获取要下载的文件的绝对路径
    String realPath = this.getServletContext().getRealPath("/download/1.JPG");
    //2.获取要下载的文件名
    String fileName = realPath.substring(realPath.lastIndexOf("\\")+1);
    //3.设置content-disposition响应头控制浏览器以下载的形式打开文件
    response.setHeader("content-disposition", "attachment;filename="+fileName);
    //需要注意的地方就是中文文件名要使用URLEncoder.encode方法进行编码(URLEncoder.encode(fileName, "字符编码")),否则会出现文件名乱码。
            response.setHeader("content-disposition", "attachment;filename="+URLEncoder.encode(fileName, "UTF-8"));
    //4.获取要下载的文件输入流
    InputStream in = new FileInputStream(realPath);
    int len = 0;
    //5.创建数据缓冲区
    byte[] buffer = new byte[1024];
    //6.通过response对象获取OutputStream流
    OutputStream out = response.getOutputStream();
    //7.将FileInputStream流写入到buffer缓冲区
    while ((len = in.read(buffer)) > 0) {
    //8.使用OutputStream将缓冲区的数据输出到客户端浏览器
    out.write(buffer,0,len);
    }
    in.close();
    }

Java Web开发总结(一)的更多相关文章

  1. Java Web开发中MVC设计模式简介

    一.有关Java Web与MVC设计模式 学习过基本Java Web开发的人都已经了解了如何编写基本的Servlet,如何编写jsp及如何更新浏览器中显示的内容.但是我们之前自己编写的应用一般存在无条 ...

  2. 【转】 java web开发之安全事项

    从事java web开发也有几年了,可是开发中的安全问题却越来越不以为然.直到不久遇到一黑软,瞬间sql注入,少时攻破网站数据库.还好,我还没有用root级的用户连接数据库.不过也没有什么用了,因为我 ...

  3. 【原创】三分钟教你学会MVC框架——基于java web开发(2)

    没想到我的上一篇博客有这么多人看,还有几位看完之后给我留言加油,不胜感激,备受鼓励,啥都别说了,继续系列文章之第二篇.(如果没看过我第一篇博客的朋友,可以到我的主页上先浏览完再看这篇文章,以免上下文对 ...

  4. [Java Web整合开发王者归来·刘京华] 1、 Java Web开发

      目录: 1.Web技术简介 2.动态网站与静态网站 3.Java Web开发模式 4.JavaScript简介 1.Web技术简介 PS: 最近还有更凶残的技术,即整个操作系统都是基于Web的,如 ...

  5. 个人的java web开发书单

    首发至个人博客http://www.zidafone.com/blog/36 以下是对一些读过的书和一些买后随便翻了翻的书的个人感觉.都是java web开发的程序员可能接触的书,其他的如设计/手机开 ...

  6. java web开发必备知识

    从各种招聘网站的要求上筛选出了一些java开发的一些基本的要求,对照自身看看有哪些缺陷. java基础 既然是java web开发,java SE肯定要学好了. 多线程,IO,集合等,对队列,缓存,消 ...

  7. Java Web开发之详解JSP

    JSP作为Java Web开发中比较重要的技术,一般当作视图(View)的技术所使用,即用来展现页面.Servlet由于其本身不适合作为表现层技术,所以一般被当作控制器(Controller)所使用, ...

  8. Java Web开发介绍

    转自:http://www.cnblogs.com/pythontesting/p/4963021.html Java Web开发介绍 简介 Java很好地支持web开发,在桌面上Eclipse RC ...

  9. 《Java web 开发实战经典》读书笔记

    去年年末,也就是大四上学期快要结束的时候,当时保研的事情确定了下来,终于有了一些空闲的时间可以学点实用的技术. 之前做数据库课程设计的时候,也接触过java web的知识,当时做了一个卖二手书籍的网站 ...

  10. 使用Eclipse+Maven+Jetty构建Java Web开发环境(几个教程综合集成2014发行)

    工作需要使用Jetty由于web集装箱,得知Eclipse+Maven+Jetty该组合是非常好的,因此,要在网上找了很多教程,但不写或多或少特定的或过时的内容而导致最终的配置失败,易于配置为未来的同 ...

随机推荐

  1. java tomcat linux 环境变量设置

    一https://www.cnblogs.com/hanshuai/p/9604730.html :whereis java //查找java 安装路径:which java //查找java 执行路 ...

  2. hdu5178 尺取

    会爆int /* 给定数轴上一些点对,问有多少点对之间的距离差不超过k 点对排序后尺取法:枚举每个左边界,找到一个右边界使得 */ #include<bits/stdc++.h> #def ...

  3. *****hibernate主键生成

    一.主键主键是关系数据库中的一个基本概念,它用来保证记录的唯一性主键都是没有业务含义的,所以开发 者不会.也不需要,显示地设置实体对象的主键值.但是对于数据库来说,主键是必须的 Hibernate内置 ...

  4. 《转》String,StringBuffer与StringBuilder的区别??

    String 字符串常量StringBuffer 字符串变量(线程安全)StringBuilder 字符串变量(非线程安全) 简要的说, String 类型和 StringBuffer 类型的主要性能 ...

  5. jQuery中的CSS(二)

    一:获取样式和设置样式

  6. python:a += b 和 a = a + b

    在python中,不同的情况下,这两个表达式有着很大的区别: 如果a,b都是可变对象,例如list,a+=b实际是对a指向的地址上的值进行修改,即运算前后id(a)的值是不变的. 而a=a+b是不同的 ...

  7. BZOJ1084 [SCOI2005]最大子矩阵 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1084 题意概括 这里有一个n*m的矩阵,请你选出其中k个子矩阵,使得这个k个子矩阵分值之和最大.注 ...

  8. vi中批量加注释

    用v进入virtual模式 按Control+v(win下面ctrl+q)进入列模式 上下键来进行选择 I进行输入(shift+i) 按两次ese键

  9. ATM+购物车商城

    模拟实现一个ATM + 购物商城程序 额度 15000或自定义 实现购物商城,买东西加入 购物车,调用信用卡接口结账 可以提现,手续费5% 支持多账户登录 支持账户间转账 记录每月日常消费流水 提供还 ...

  10. PHP 扩展 MongoDB

    打开phpinfo 查看 nts(非线程) 还是 ts (线程),操作位数: 下载对应的版本的php_mongodb.dll 文件 下载链接: pecl mangodb下载 把文件解压出来 php_m ...