三、java WEB的开发
1.服务器的配置
服务器的详细安装步骤可以看我的博客:
工欲善其事必先利器——apache tomcat服务器的搭建
WEB中为了方便用户的访问,可以把端口号设置为80 具体位置应该在Tomcat安装目录下的 server.xml 比如我的: \Tomcat 6.0\conf\server.xml
修改server.xml 文件中的配置,
找到
<
Connector
port
="
8080
"
protocol
="
HTTP/1.1
"
connectionTimeout
="
20000
"
redirectPort
="
8443
"
/>
将默认的8080 端口号改为80
<
Connector
port
="
80
"
protocol
="
HTTP/1.1
"
connectionTimeout
="
20000
"
redirectPort
="
8443
"
/>
为了让我们开发的东西能够让外界访问,还需要在这个server.xml 中的</Host>节点前设置外界要访问我们电脑磁盘上的那个文件格式如下
<Context path=" /wangjie" docBase="E:\android"/>
其中的path 是虚拟目录 docBase 是指磁盘上的位置
正常情况下tomcat会出现这样的错误,404表示客户端错误,是因为tomcat中将目录的列表功能给关闭了,所以看不到,需要修改 \Tomcat 6.0\conf下的web.xml文件下是listings的权限改为true,平常的时候可以看见,但如果发布的时候为了安全,可以在改回来
<即将
<
init-param
>
<
param-name
>
listings
</
param-name
>
<
param-value
>
false
</
param-value
>
</
init-param
>
改为
<<
init-param
>
<
param-name
>
listings
</
param-name
>
<
param-value
>true
</
param-value
>
</
init-param
>
不过这些都有点缺点,配置好后需要重新启动服务器
<
2.http请求
1.一个http请求包含: 一个请求行、 若干个请求头 、以及实体内容、;
请求行:用于描述客户端的请求方式,请求资源的名称,以及使用的HTTP的版本号。
请求行中有7中请求方式:
GET POST HEAD OPTIONS DELETE TRACE PUT
GET 或者 POST 都是用于向服务器请求某个WEB资源,这两种方式的区别主要表现在数据的传递上:
GET请求:可以在请求的URL地址后面以?的形式带上提交给服务器的数据,多个数据之间用& 进行分割,参数的数据容量不能超过1K ,而POST则无限制
例如:GET /mail/1.html?name=aaa&password=12345 HTTP/1.1
请求头:用于描述客户端请求的那台主机,以及客户端的一些环境信息
消息头:
![](https://img-my.csdn.net/uploads/201304/06/1365255541_1200.png)
2.HTTP 响应包括: 一个状态行、若干消息头、以及实体内容
状态行:用于描述服务器对请求的处理结果
多个响应头:消息头用于描述服务器的基本信息,以及数据的描述信息,可以通知客户端如何处理会送的数据
实体内容:服务器系那个客户端会送的数据
状态码:用于表示服务器对请求的处理结果,一般用3位十进制数表示,响应状态码分为5类,如下:
![](https://img-my.csdn.net/uploads/201304/07/1365292713_1868.png)
ps:200 成功接收,并完成处理过程 302 服务器建议找别的地址 304和307 拿缓存 404 客户端地址错误,没有资源 403 没有权限 500 服务器出错,即编程出错
3.HTTP常用的响应头
1.响应头如下:
![](https://img-my.csdn.net/uploads/201304/07/1365297975_3949.png)
2.Content-Encoding------实现数据的压缩功能
/****
*
* 数据的压缩
* **/
private void test2(HttpServletResponse response) throws IOException {
String data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
System.out.println("原始数据的大小:" + data.length());
ByteArrayOutputStream bout = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(bout);
gout.write(data.getBytes());
gout.close();
// 得到压缩后的数据
byte gzip[] = bout.toByteArray();
System.out.println("压缩后的大小" + gzip.length);
// 通知浏览器数据采用的压缩格式
response.setHeader("Content-Encoding", "gzip");
response.setHeader("Content-Length", gzip.length + "");
response.getOutputStream().write(gzip);
}
3.content-type --- 控制以那个方式处理数据
/**
* 通过content-type的头字段,控制以那个方式处理数据
* ***/
private void Test3(HttpServletResponse response) throws IOException {
response.setHeader("content-type", "image/jpeg");
InputStream in = this.getServletContext().getResourceAsStream("/2.jpg");
int len = 0;
byte buffer[] = new byte[1024];
OutputStream outputStream = response.getOutputStream();
while ((len = in.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
}
4.refresh头--- 实现定时刷新
/***
* refresh头字段的用法,每隔3秒访问以下百度
* **/
private void test4(HttpServletResponse response) throws IOException {
response.setHeader("refresh", "3;url='http://www.baidu.com'");
String data="111111111111";
response.getOutputStream().write(data.getBytes());
}
5.content-dispostion头---实现下载功能
//实现下载功能
private void test5(HttpServletResponse response) throws IOException {
response.setHeader("content-dispostion", "attachment;filename=3.jpg");
InputStream in = this.getServletContext().getResourceAsStream("/3.jpg");
int len = 0;
byte buffer[] = new byte[1024];
OutputStream outputStream = response.getOutputStream();
while ((len = in.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
}
6.range -----头可以实现断点下载的功能
// 实现断点续传
public static void main(String[] args) throws Exception {
URL url = new URL("http://localhost/web01/a.txt");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Range", "bytes=5-");
InputStream inputStream = connection.getInputStream();
int len = 0;
byte buffer[] = new byte[1024];
FileOutputStream outputStream = new FileOutputStream("d:\\a.txt", true);
while ((len = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, len);
}
inputStream.close();
outputStream.close();
}
4.Servlet的一些东西
1.关于映射问题采取最相像的那个映射地址:
线程安全问题:即操作共享资源问题,如果多个资源同时操作它,就会出现线程安全问题
public class ServletDemo1 extends HttpServlet implements SingleThreadModel {
int i = 0;
//线程安全问题:用synchronized 解决
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
i++;
try {
Thread.sleep(1000 * 3);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
response.getOutputStream().write((i + " ").getBytes());
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
2.Servlet的初始化配置问题
获取Servlet 的配置信息的方法
public class SevletConfig extends HttpServlet {
/*****
* ServletConfig 对象:用于封装servlet的配置信息
* 在实际开发中,有一些东西不是适合在servlet程序中写死,这类数据可以通过配置方式配置给Servlet 比如: servlet 采用哪个码表
* servlet 链接哪个库, servlet 哪个配置文件
*
* ********/
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 得到指定的配置
String value = this.getServletConfig().getInitParameter("data");
System.out.println(value);
// 得到所有的配置信息
Enumeration enumeration = this.getServletConfig()
.getInitParameterNames();
while (enumeration.hasMoreElements()) {
String name = (String) enumeration.nextElement();
String valueall = this.getServletConfig().getInitParameter(name);
System.out.println(name + "==" + valueall);
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
Servlet的配置信息如下:
<servlet>
<servlet-name>SevletConfig</servlet-name>
<servlet-class>com.nyist.servlet.SevletConfig</servlet-class>
<init-param>
<param-name>data</param-name>
<param-value>dddddd</param-value>
</init-param>
<init-param>
<param-name>data1</param-name>
<param-value>hhhhh</param-value>
</init-param>
<init-param>
<param-name>config</param-name>
<param-value>/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:80/test</param-value>
</init-param>
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>password</param-name>
<param-value>root</param-value>
</init-param>
</servlet>
3.得到ServletContext的方法可以实现多个Servlet的数据共享
ServletContext 域:
1.这是一个容器
2.ServletContext 域,说明这个容器的范围,也就是应用范围
在doGet方法中
//1、 得到Servletcontext的方法
ServletContext context=this.getServletConfig().getServletContext();
//2
context=this.getServletContext();
1.数据共享例子 发布1的servlet
String putdata="传递数据";
this.getServletContext().setAttribute("datastr", putdata);
共享数据2
String value=(String) this.getServletContext().getAttribute("datastr");
System.out.println(value);
2、获取web应用的初始化参数
String value=this.getServletContext().getInitParameter("data");
response.getOutputStream().write(("<font color='red'>")+value+"</font>").getBytes();
3.servlet实现数据转发的功能
// 下面是通过ServletContext 实现请求转发的功能
String data="ddddddddddddddd";
// 把数据带个1.jsp (不能通过context 域 需要通过request域)
this.getServletContext().setAttribute("data", data);
RequestDispatcher requestDispatcher=this.getServletContext().getRequestDispatcher("/1.jsp");
requestDispatcher.forward(request, response);
1.jsp
body>
This is my JSP page.
<br>
<h1>
<font color="red"> <%
String data = (String) application.getAttribute("data");
out.write(data);
%> </font>
</h1>
</body>
4.利用ServletContext对象读取资源文件
/****
* 读取资源文件 其中db.properties的路径 如果有包名则换成文件名 如com.nyist.servlet
* 应该为com/nyist/servlet/db.properties 如果放在WEB-INF下直接就可以使用 db.properties
*
*
* **/
InputStream inputStream = this.getServletContext().getResourceAsStream(
"/WEB-INF/classes/db.properties");
/**
* 或者还有一个方法可以替换上一句代码 调用getServletContext 获取资源的绝对路径,
* 再通过传统的流读取资源文件,有点是可以获取当前读取资源文件的名称
*
* String path = this.getServletContext().getRealPath(
* "WEB-INF/classes/db.properties"); // \ 转义字符获取最后一个斜杠后面的文件名称\ String
* filename=path.substring(path.lastIndexOf("\\")+1);
* System.out.println("当前资源的名称是:"+filename); FileInputStream
* inputStream1 = new FileInputStream(path);
* **/
Properties properties = new Properties();
properties.load(inputStream);
String url = properties.getProperty("url");
String usrname = properties.getProperty("usrname");
String password = properties.getProperty("password");
System.out.println(url);
System.out.println(usrname);
System.out.println(password);
db.properties的文件如下
url=jdbc:mysql://localhost:80/test
usrname=root
password=root
5.使用类装载器读取资源文件
// 使用Servlet调用其它程序
ServletContext context = this.getServletContext();
UsrDao dao = new UsrDao();
dao.update();
UsrDao的类如下:
public class UsrDao {
public void update() throws Exception {
String path = UsrDao.class.getClassLoader()
.getResource("db.properties").getPath();
FileInputStream inputStream = new FileInputStream(path);
Properties properties = new Properties();
properties.load(inputStream);
System.out.println(properties.getProperty("url"));
}
}