(起因是eclipse集成插件实现了J2EE的模拟服务器运行,但每次打开太慢,图片等预览效果不好,就想着只用tomcat服务器,集成自己的web项目,,然后我又把能遇到的问题都遇了个遍。。。)
一、目录结构。
.java文件编译成的.class文件是放在WEB-INF的classes文件夹里的,可能是跟tomcat内部的文件解析找寻有关。
web.xml里面储存的是servlet地址映射和项目首页设置之类的,是放在WEB-INF文件夹里的。(这个是由F:\apache-tomcat-7.0.94\conf\context.xml文件决定的,内容如下:)
context.xml:
参考教程:https://www.cnblogs.com/bennyblue/p/3365715.html
二、server.xml注册项目及相应端口。
F:\apache-tomcat-7.0.94\conf\server.xml
<!--Server负责监听关闭tomcat的请求-->
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener"/>
<Listener SSLEngine="on" className="org.apache.catalina.core.AprLifecycleListener"/>
<Listener className="org.apache.catalina.core.JasperListener"/>
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/>
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/>
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/>
<GlobalNamingResources>
<Resource auth="Container" description="User database that can be updated and saved" factory="org.apache.catalina.users.MemoryUserDatabaseFactory" name="UserDatabase" pathname="conf/tomcat-users.xml" type="org.apache.catalina.UserDatabase"/>
</GlobalNamingResources>
<Service name="Catalina"><!--生成F:\apache-tomcat-7.0.94\conf\Catalina文件夹-->
<!--Connector接收用户请求,返回结果(其实就是标识端口的,这里是8080端口)-->
<Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443"/><!--8009端口转接其他服务器的请求,可与IIS绑定等-->
<!--Engine接收处理来自一个Service的多个Connector请求,(获得请求localhost/test/hello.jsp,传给名为localhost的虚拟主机)-->
<Engine defaultHost="localhost" name="Catalina"><!--生成F:\apache-tomcat-7.0.94\conf\Catalina\localhost文件夹,defaultHost为默认打开的虚拟主机-->
<Realm className="org.apache.catalina.realm.LockOutRealm"><!--存放用户名,调试和错误信息->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm" resourceName="UserDatabase"/>
</Realm>
<Host appBase="webapps" autoDeploy="true" name="localhost" unpackWARs="true">
</Host>
<!--Host表示一个虚拟主机,里面有多个web应用(获得请求test/hello.jsp,传给test应用)-->
<Host name="www.test.com" debug="0" appBase="webapps" unpackWARs="true" autoDeploy="false" xmlValidation="false" xmlNamespaceAware="false"> <!--appBase对应F:\apache-tomcat-7.0.94\webapps文件夹,autoDeploy表示是否自动加入新的web应用-->
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs" pattern="%h %l %u %t "%r" %s %b" prefix="test_access_log." suffix=".txt"/><!--这里是日志文件,与<Logger>差不多,在F:\apache-tomcat-7.0.94\logs\test_access_log.txt文件-->
<!--Context表示虚拟主机里的单个web应用(获得请求hello.jsp,处理找寻新建相应servlet,构建HttpServletRequest和HttpServletResponse对象,调用doGet() doPost()方法,逐级返回response)-->
<Context path="" docBase="F:\apache-tomcat-7.0.94\webapps\test" debug="0" reloadable="true" ><!--docBase对应F:\apache-tomcat-7.0.94\webapps\test文件夹,是项目的主文件夹,path为请求访问时候的url前缀,空的话就指的docBase目录,reloadable属性为true可以在不重启tomcat的情况下改变应用程序-->
</Context>
</Host><!--本地测试的时候就可以用www.test.com:8080/hello.jsp访问-->
</Engine>
</Service>
</Server>
server.xml各成分详解链接:https://www.cnblogs.com/starhu/p/5599773.html
也可以自己构建其他端口的应用(我这里兼容了80端口):
三、设置网站默认首页。
F:\apache-tomcat-7.0.94\webapps\test\WEB-INF\web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<welcome-file-list>
<welcome-file>hello.jsp</welcome-file><!--一级默认页面,即http://www.test.com:8080即可访问到-->
<welcome-file>iisstart.htm</welcome-file><!--二级页面,一级页面丢失时-->
</welcome-file-list>
</web-app>
四、前端访问servlet的三种方法(ajax、jsp、xmlHttpRequest主要代码)
(报错:如果是404的错误,一般就是映射路径问题;如果是500错误,可能是后台servlet代码的问题)
1.ajax
Hello.html文件:
F:\apache-tomcat-7.0.94\webapps\test\Hello.html
<script src="jquery.min.js"></script>
<script type="text/javascript">
$.ajax({
//type: "get",//这里注意,本get与下面的contentType: 'application/json',配对使用,,但是请求头过大时要用post
type: "post",//本post与下面的contentType: 'application/x-www-form-urlencoded'配对使用
url:"HelloServlet",//这里前面不要"/",对应servlet的文件名
data:{message:"ok"},//这里传数据,变量名不用加引号(JSON格式)
dataType: 'json',
//contentType: 'application/json',
contentType: 'application/x-www-form-urlencoded',
async: true, //默认是true:异步,false:同步。
success: function (data) {
if(data.success){
alert('上传成功');
}
else{
alert('上传失败');
}
},
error: function (data) {
alert('网络故障');
}
});
</script>
HelloServlet.java文件:
F:\apache-tomcat-7.0.94\webapps\test\HelloServlet.java
public class HelloServlet extends HttpServlet {
//public class公共类的类名要跟文件名一致!
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String message = request.getParameter("message");//获得前端传的数据
//System.out.println(message);//这里输出在了tomcat服务器界面里
response.setContentType("text/html;charset=utf-8");
response.setHeader("charset", "utf-8");
PrintWriter out=response.getWriter();
out.write("<h1>"+message+"</h1>");
//response.getWriter().print("{\"success\":\""+ true +"\"}");//表示{"success":"true"}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
}
web.xml映射文件:
F:\apache-tomcat-7.0.94\webapps\test\WEB-INF\web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app>
<servlet>
<servlet-name>HelloServlet</servlet-name> <!--对应servlet的文件名-->
<servlet-class>HelloServlet</servlet-class> <!--对应继承HttpServlet的servlet的类名-->
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name> <!--对应servlet的文件名-->
<url-pattern>/HelloServlet</url-pattern> <!--对应访问的url,要有"/"-->
</servlet-mapping>
</web-app>
2.jsp
hello.jsp文件:
F:\apache-tomcat-7.0.94\webapps\test\hello.jsp
<form action="HelloServlet"><!--对应servlet的文件名-->
<a href="HelloServlet">request servlet</a>
HelloServlet.java文件:
F:\apache-tomcat-7.0.94\webapps\test\HelloServlet.java
@WebServlet("/HelloServlet") //没有";"分号,有"/",对应类名,servlet有了这种@WebServlet语法就可直接找寻对应class类了,不用配置web.xml映射
public class HelloServlet extends HttpServlet {
...
}
}
3.XMLHttpRequest
hello.html文件:
<script type="text/javascript">
//利用XMLHttpRequest向服务端传递数据
var xmlhttp;//创建xhr
if(window.XMLHttpRequest) //IE7+ Firefox Chrome Opera Safari
xmlhttp=new XMLHttpRequest();
else //IE6 IE7 浏览器执行代码
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
var url="HelloServlet";//servlet地址
xmlhttp.open("get",url,true);//true代表异步
xmlhttp.onreadystatechange=function(){
if(this.readyState==4&&this.status==200){
//如果正常返回。。。
alert("SUCCEED");
//alert(xmlhttp.responseText);//可读取服务端返回的数据
//console.log(xmlhttp.responseText) ;//在console输出也是很好的debug的方式
}
}
xmlhttp.setRequestHeader("Content-type","application/json");//请求头
xmlhttp.send({message:"ok"});//也可以是其他类型的数据
</script>
servlet文件:略,同上。
五、编译.class文件
(.class文件是二进制流,更具有跨平台兼容性,所有平台的jvm都可以使用,所以最后解析的是.class文件)
注意:tomcat中.class文件要放在(例)F:\apache-tomcat-7.0.94\webapps\test\WEB-INF\classes里面
1.(cmd)javac命令:
javac -encoding utf-8 -d F:\apache-tomcat-7.0.94\webapps\test\WEB-INF\classes F:\apache-tomcat-7.0.94\webapps\test\HelloServlet.java
(-d是HelloServlet.class文件保存的目录,没有的话就保存到了HelloServlet.java同目录下)
注意:javac命令环境变量配置的path用C:\Program Files\Java\jdk1.8.0_144\jre\bin;C:\Program Files\Java\jdk1.8.0_144\bin绝对地址,不要用%JAVA_HOME%/...相对地址,javac.exe的程序就在jdk\bin里面
可能报错:非法字符:“\ufeff”,... ,需要class,interface,enum,... 。是保存格式GBK或者UTF-8 with BOM的问题,需上文命令是-encoding utf-8,所以.java文件要用utf-8的编码格式保存。VS中修改是ctrl+shift+p->更改文件编码;或者文件->首选项->设置->encode里的编码格式默认值修改)
2.JavaComplier:
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
JavaCompiler compiler=ToolProvider.getSystemJavaCompiler();
compiler.run(null,null,null,"F:\\apache-tomcat-7.0.94\\webapp\\test\\HelloServlet.java");
可能报错:程序包javax.servlet.*不存在。设置环境变量CLASSPATH为F:\apache-tomcat-7.0.94\lib\servlet-api.jar(servlet接口配置),并把该jar包拷到jdk\jre\lib\ext下。
参考教程:https://blog.youkuaiyun.com/u010897392/article/details/50162809
六、chrome开发者工具使用
ctrl+shift+I或右上角的首页->更多工具->开发者工具
点击request servlet后
Network下点开现在运行的文件名,可看到请求该文件页面的request与response请求头、响应情况等,可追踪报错。