JavaWeb就是在服务器端以Java语言为解释运行基础的web程序。
php代码要想在服务器端运行,需要在服务器软件(通常是Apache)上加php的解释器,Java也一样,但是这个解释器是Tomcat。但还是有点不一样,可能与两种语言的特性有关:php是脚本语言,解释执行;而Java需要编译执行。php解释器添加到Apache上就可以了,但是只是将请求转交给Tomcat来执行并返回结果。(具体区别以后总结)
在eclipse中设置Javaweb环境
java web开发的基础:servlet
servlet是java提供的用于远程访问的接口,有一个http专用的子接口httpservlet抽象类,开发者只需要继承/实现相应类/接口即可进行http访问即web开发。有三种途径
1、实现javax.servlet.Servlet接口; --》顶层接口,只是定义了几个生命周期方法和简单方法
2、 继承javax.servlet.GenericServlet类; --》servlet接口的简单实现
3、 继承javax.servlet.http.HttpServlet类; --》专用于http协议的GenericServlet类的实现,注意这个类是没有抽象方法的抽象类
而tomcat的作用就是
①建立低层的连接,
②将请求信息封装为java对象(如ServletConfig,(Http)ServletRequest等,这是接口,有tomcat实现并传入),重要,需要掌握这些对象的用法。
参考:http://blog.csdn.net/tong_xinglong/article/details/12972819
http://blog.sina.com.cn/s/blog_696024a90100o6hq.html
③调用相应的servlet,通过web.xml配置文件
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <servlet> 2 <servlet-name>AServlet</servlet-name> 3 <servlet-class>hello.AServlet</servlet-class> 4 <init-param> 5 <param-name>p1</param-name> 6 <param-value>v1</param-value> 7 </init-param> 8 <init-param> 9 <param-name>p2</param-name> 10 <param-value>v2</param-value> 11 </init-param> 12 </servlet> 13 <servlet-mapping> 14 <servlet-name>AServlet</servlet-name> 15 <url-pattern>/aservlet</url-pattern> 16 </servlet-mapping>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package hello; 2 3 import java.io.IOException; 4 import java.util.Enumeration; 5 6 import javax.servlet.Servlet; 7 import javax.servlet.ServletConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 12 /*Servlet是该体系的顶端接口 13 * 14 */ 15 public class AServlet implements Servlet { 16 17 private ServletConfig sc; 18 19 @Override 20 /*生命周期方法:!!!初始化方法,在servlet在被tomcat创建时调用,只有一次,在执行构造函数方法之后立即被调用 21 *注意:声明周期方法是被tomcat调用,所以传入的参数是由其自动传入,而且该对象也是有tomcat创建的, 22 * 但是依据的是用户自己的web.xml配置文件 23 * 24 * 初始化方法通常用来给servlet类进行赋值 25 */ 26 public void init(ServletConfig ServletConfig) throws ServletException { 27 System.out.println("init..."); 28 //使用tomcat提供的SerletConfig对象获取对应配置信息 29 Enumeration<String> e=ServletConfig.getInitParameterNames(); 30 while(e.hasMoreElements()){ 31 String para=e.nextElement(); 32 System.out.println(para+"..."+ServletConfig.getInitParameter(para)); 33 } 34 35 this.sc=ServletConfig; 36 this.init(); 37 } 38 39 public void init() { 40 /*!!!该方法留空,是留给子类(如果有)覆盖的,不要是覆盖生命周期方法,因为其需要对该类进行配置 41 * 这里要再次注意:Java中函数只要返回值/参数个数/参数类型 不同即使重写 42 * 该方法只要在生命周期的init方法中调用即可,由继承的特点即可工作 43 * 44 * 这也是GenericServlet类中使用的方式 45 */ 46 } 47 48 @Override 49 public ServletConfig getServletConfig() { 50 System.out.println("getServletConfig..."); 51 return this.sc; 52 } 53 54 @Override 55 public String getServletInfo() { 56 System.out.println("getServletInfo..."); 57 return null; 58 } 59 60 /*生命周期方法:每次请求servlet都会调用,在init方法之后 61 * 62 */ 63 @Override 64 public void service(ServletRequest ServletRequest, ServletResponse ServletResponse) 65 throws ServletException, IOException { 66 System.out.println("service..."); 67 } 68 69 /*生命周期方法:销毁方法。注意并不是真正的删除对象,删除是垃圾回收器的任务,这里只是切断与对象的连接 70 *同样只执行一次 71 */ 72 @Override 73 public void destroy() { 74 System.out.println("destroy..."); 75 } 76 77 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package hello; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebInitParam; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class BServlet extends HttpServlet { private static final long serialVersionUID = 1L; //注意这里的两个方法:doGet()和doPost()必须实现一个 //就是使用的传输方法:get/post,就实现对应的方法 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doGet..."); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("doPost..."); } } 、、
servlet细节:
1、每个servlet只会生成一个类实例,即单例模式,所以有线程安全问题。线程安全的解决方法有
1、不在servlet中创建成员,使用局部变量
2、可以创建无状态成员。所谓状态成员也就是描述一个事物的,即类的属性。
3、创建有状态成员,但是状态必须是只读的。也就是说可以有属性,但是只有读取的方法而没有写的方法。
2、servlet对象的创建时间:默认是在用户首次调用时创建对象,所以第一次使用时较慢;但是可以在web.xml中对应的servlet配置中配置一条
<load-on-startup>0</load-on-startup>,只要值>=0即可在tomcat开启时自动创建。如果有多个,则按照值升序依次创建
3、在web.xml配置<url-pattern>的值可以有多个与一个<servlet-name>对应,并且可以使用*通配符。
注意:通配符只能放在开头(匹配路径)或结尾(匹配扩展名)。
匹配的优先级:具体的路径(/a/b.jsp)>使用通配符的路径(/a/b.*)>根路径(/,匹配所有路径)
web.xml中的默认配置有以下作用
1、servlet和JSP的关系:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <servlet> 2 <servlet-name>jsp</servlet-name> 3 <servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class> 4 <init-param> 5 <param-name>fork</param-name> 6 <param-value>false</param-value> 7 </init-param> 8 <init-param> 9 <param-name>xpoweredBy</param-name> 10 <param-value>false</param-value> 11 </init-param> 12 <load-on-startup>3</load-on-startup> 13 </servlet> 14 15 <servlet-mapping> 16 <servlet-name>jsp</servlet-name> 17 <url-pattern>*.jsp</url-pattern> 18 <url-pattern>*.jspx</url-pattern> 19 </servlet-mapping>
由配置信息可知:所有以JSP结尾的文件都会转交到org.apache.jasper.servlet.JspServlet这个类中进行处理
2、访问一个不存在的路径时显示404页面
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <servlet> 2 <servlet-name>default</servlet-name> 3 <servlet-class>org.apache.catalina.servlets.DefaultServlet</servlet-class> 4 <init-param> 5 <param-name>debug</param-name> 6 <param-value>0</param-value> 7 </init-param> 8 <init-param> 9 <param-name>listings</param-name> 10 <param-value>false</param-value> 11 </init-param> 12 <load-on-startup>1</load-on-startup> 13 </servlet> 14 15 <servlet-mapping> 16 <servlet-name>default</servlet-name> 17 <url-pattern>/</url-pattern> 18 </servlet-mapping>
由配置信息可知:所有没有其他servlet接收的路径(即无效不存在的路径)都会被转到org.apache.catalina.servlets.DefaultServlet中去处理,就是显示404页面
3、配置session,以后使用
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <session-config> 2 <session-timeout>30</session-timeout> 3 </session-config>
参考:http://blog.csdn.net/guihaijinfen/article/details/8363839
servlet是通过配置文件,使用反射技术产生对象实例的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package hello; 2 3 import java.io.BufferedReader; 4 import java.io.IOException; 5 import java.io.InputStream; 6 import java.io.InputStreamReader; 7 import java.util.Set; 8 9 import javax.servlet.ServletContext; 10 import javax.servlet.ServletException; 11 import javax.servlet.annotation.WebServlet; 12 import javax.servlet.http.HttpServlet; 13 import javax.servlet.http.HttpServletRequest; 14 import javax.servlet.http.HttpServletResponse; 15 16 /** 17 * Servlet implementation class CServlet 18 */ 19 @WebServlet("/CServlet") 20 public class CServlet extends HttpServlet { 21 private static final long serialVersionUID = 1L; 22 23 /** 24 * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) 25 */ 26 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 27 //获取Servlet公共配置参数示例 28 getInitPara(); 29 //获取该项目下的资源 30 getPath(); 31 //获取该项目的类资源 32 getClassPath1(); 33 getClassPath2(); 34 } 35 36 private void getInitPara() { 37 /*Servlet除了可以使用自己局部的参数,还可以使用公共的配置参数,即<context-para>中的配置参数 38 * 必须通过ServletContext对象的方法来获取 39 */ 40 ServletContext app=this.getServletContext(); 41 String context_value=app.getInitParameter("context-para"); 42 System.out.println(context_value); 43 } 44 45 private void getPath() { 46 //获取该项目中指定资源的真实路径,带盘符 47 String realPath=this.getServletContext().getRealPath("/index.jsp"); 48 //D:\Java\tomcat\apache-tomcat-7.0.42\me-webapps\hello\index.jsp 49 System.out.println(realPath); 50 51 //还可以进一步获取流对象 52 //InputStream is=this.getServletContext().getResourceAsStream("/index.jsp"); 53 54 //还可以获取一个路径下的所有资源路径,注意只是浅获取,即只获取该目录下而不向下获取,用Set集合保存 55 Set<String> set=this.getServletContext().getResourcePaths("/WEB-INF"); 56 System.out.println(set); 57 } 58 59 private void getClassPath1() throws IOException { 60 //获取类路径下资源,通过ClassLoader对象,在获取该资源的输入流对象就可以读取资源(文件)的内容了 61 ClassLoader cl=this.getClass().getClassLoader(); 62 //注意:使用ClassLoader对象时,这里的路径是相对于 /项目/WEB-INF/classes ,也就是编辑器中的 /src 63 InputStream is=cl.getResourceAsStream("/a.txt"); 64 BufferedReader br=new BufferedReader(new InputStreamReader(is)); 65 String line=""; 66 while((line=br.readLine())!=null){ 67 System.out.println(line); 68 } 69 } 70 71 private void getClassPath2() throws IOException { 72 //获取类路径下资源,通过Class对象,在获取该资源的输入流对象就可以读取资源(文件)的内容了 73 Class<? extends CServlet> c=this.getClass(); 74 /*注意:使用Class对象时, 75 * 如果路径以 / 开头,则相对 /项目/WEB-INF/classes ,也就是编辑器中的 /src 76 * 如果不以 / 开头,则相对于当前servlet路径 77 */ 78 InputStream is=c.getResourceAsStream("a.txt"); 79 is=c.getResourceAsStream("/../../index.jsp"); 80 BufferedReader br=new BufferedReader(new InputStreamReader(is)); 81 String line=""; 82 while((line=br.readLine())!=null){ 83 System.out.println(line); 84 } 85 } 86 87 }
HTTP访问乱码问题:
1、客户端:最常见的是浏览器,在url中有中文时,最好使用URLEncoder对其进行编码,而且最好使用UTF-8编码
2、服务器端:
①接收数据:通过servlet接收,然后通过getParameter()进行获取时,使用的编码默认是iso-8859-1,所以要对接收到的数据进行重新转码包装
②响应数据:首先使用iso-8859-1编码,如果超过编码范围则使用系统编码,