javaWeb学习之旅(三)-----java WEB的开发入门

时间:2023-02-16 12:01:55

三、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      请求头:用于描述客户端请求的那台主机,以及客户端的一些环境信息       消息头: javaWeb学习之旅(三)-----java WEB的开发入门

2.HTTP  响应包括: 一个状态行、若干消息头、以及实体内容

                            状态行:用于描述服务器对请求的处理结果                             多个响应头:消息头用于描述服务器的基本信息,以及数据的描述信息,可以通知客户端如何处理会送的数据                            实体内容:服务器系那个客户端会送的数据 状态码:用于表示服务器对请求的处理结果,一般用3位十进制数表示,响应状态码分为5类,如下:javaWeb学习之旅(三)-----java WEB的开发入门
ps:200 成功接收,并完成处理过程     302 服务器建议找别的地址     304和307 拿缓存     404 客户端地址错误,没有资源   403 没有权限    500 服务器出错,即编程出错

3.HTTP常用的响应头

1.响应头如下:
javaWeb学习之旅(三)-----java WEB的开发入门
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);
}

}

ps:java中子类不能比父类抛出的异常多。。。

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"));

}

}