serlvet和jsp区别和联系
jsp从本质上讲也是servlet
servlet的优势:处理业务逻辑方便(访问数据库方便) 劣势:显示内容给浏览器繁琐
jsp的优势:显示内容给浏览器方便 劣势:处理业务逻辑繁琐
所以得出 servlet和jsp是相辅相成的
1. post方式提交的数据 采用request.setCharacterEncoding(“gbk”);
get提交的数据 在tomcat 目录下的conf中server.xml中元素<Connector>中增加属性: useBodyEncodingForURI="true",则1中的方法对get方式提交的数据也有效
2. 通用方法 new String(str.getBytes(“iso-8859-1”),”gbk”)
以后解决乱码问题:首先将tomcat/conf/server.xml文件中的<Connector>中增加属性: useBodyEncodingForURI="true",记住这个<Connector>指的是tomcat修改端口的元素
加上这句话以后对于get或者是post的提交方式 request.setCharacterEncoding("UTF-8");都是通用的
如果说偶尔会发生加上上面这句话 有些中文问题然后乱码,用最直接的方法new String(str.getBytes(“iso-8859-1”),”gbk”)
完美解决乱码问题:第一步,将tomcat/conf/server.xml文件中<Connector>中增加属性: useBodyEncodingForURI="true",这样对于get或者post的提交方式 request.setCharacterEncoding("UTF-8");都是通用的
第二步:写一个编码集过滤器 将工程下面所有的请求都要先执行过滤器里面的代码(request.setCharacterEncoding("UTF-8");)然后再继续执行之前的请求
过滤器的写法:
1.创建一个java类 实现javax.servlet.Filter这个接口
2.在web.xml文件进行过滤器的配置 通常情况过滤器的配置写到web.xml文件的上面(servlet的上面)
package com.pk.cs.web.fliter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class FirstFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException
{
request.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
}
public void init(FilterConfig arg0) throws ServletException
{
}
}
Web.xml文件中:
<filter>
<filter-name>FirstFilter</filter-name>
<filter-class>com.pk.cs.web.fliter.FirstFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>FirstFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
过滤器
1. Servlet过滤器基础
Servlet过滤器是Servlet的一种特殊用法,主要用来完成一些通用的操作。比如编码的过滤,判断用户的登陆状态等等。Servlet过滤器的适用场合:
A.认证过滤
B.登录和审核过滤
C.图像转换过滤
D.数据压缩过滤
E.加密过滤
F.令牌过滤
G.资源访问触发事件过滤
Servlet过滤器接口的构成:
所有的Servlet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法:
方法 说明
init(FilterConfig cfg) 这是Servlet过滤器的初始化方法,性质等同与servlet的init方法。
doFilter(ServletRequest,ServletResponse,FilterChain) 完成实际的过滤操作,当请求访问过滤器关联的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain参数用于访问后续过滤器
destroy() Servlet容器在销毁过滤器实例前调用该方法,这个方法中可以释放Servlet过滤器占用的资源。,性质等同与servlet的destory()方法。
Servlet过滤器的创建步骤:
A.实现javax.servlet.Filter接口的servlet类
B.实现init方法,读取过滤器的初始化函数
C.实现doFilter方法,完成对请求或过滤的响应
D.调用FilterChain接口对象的doFilter方法,向后续的过滤器传递请求或响应
F.在web.xml中配置Filter
2.使用过滤器处理中文问题
当用用户登陆页面输入帐号时,如果输入是中文,后台servlet再次输出这个内容时,可能就会是乱码,这是因为serlvet中默认是以ISO-8859-1格式编码的,如果后台有多个Servlet,多个参数,这样就不合适,这个问题,我们可以通过一个过滤器统一解决,使后台的输出输出都支持中文!将ISO-8859-1转码为GBK的那段代码!
3.使用过滤器认证用户:
每个过滤器也可以配置初始化参数,可以将不需要过滤的地址配置到这个Filter的配置参数中,过滤时,如果请求地址在配置参数中,则放行,这样就避免了在程序中硬编码。每个Filter中初始化时,都可以得到配置对象,在Filter中配置二个不需要过滤的地址,一个是登陆页面,一个是执行登陆认证的servlet;
1. 过滤器类示例://预处理某些servlet时,用过滤器。例如:编码的过滤
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class EncodingFilter implements Filter {//过滤器是实现的接口,不是继承的类
private static String encoding;
public void destroy() {
System.out.println("过滤器被销毁!!!!!!");//WEB应用被卸载时,过滤器即被销毁
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// System.out.println("step1^^^^^^^^^^^^^");
request.setCharacterEncoding(encoding); ///现在只对post. 在server.xml中的<connector>元素的属性useBodyEncodingForURI="true"置为true,那么seCharacterEncoding也可以对get起作用。
chain.doFilter(request, response); //要加这句,才能继续执行被过滤的页面
// System.out.println("step2^^^^^^^^^^^^^"); //整个过程,doFIlter被执行是次。过滤请求执行doFilter之前的代码。过滤响应执行doFilter之后的代码。
}
public void init(FilterConfig config) throws ServletException {
System.out.println("过滤器被加载!!!!!!"); //WEB应用被加载时,过滤器即被加载
encoding = config.getInitParameter("encoding");
}
}
2. 过滤器的配置:在web.xml中
<!--过滤器的配置一般置于所有servlet(listener)配置之前 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>com.puckasoft.video.util.EncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>gbk</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<%@ page errorPage=”error.jsp” %>页面出错时跳转到error.jsp页面,一般写程序时不用,但把系统交给客户前要加上,防止出错。
basePath : <base href=”<%=basePath %>”> 默认在根目录
<%@ include file="versatile.jsp(相对位置,basePath对这里不起作用)" %>这种引入页面的方式在服务器中只会生成一个java类,且两个网页的信息都在该类中out.writer()。
动作语法include:<jsp:include page="versatile.jsp"></jsp:include>这种引入页面的方式在服务器会生成两个网页各自的java类。(basePath对include标签也无效)
动作语法forward:<jsp:forward page="../login.jsp"></jsp:forward>等价于
<%
request.getRequestDispatcher("/login.jsp").forward(request,response);
%>
<jsp:forward>标签以后的代码将不能执行。
HTML注释:<!-- -->servlet中会生成,也会发给浏览器
JSP注释(隐藏注释):<%-- --%>servlet中不生成,不发给浏览器
声明:<%! %> 声明的内容可以在服务器生成的java类代码中找到
JSP的内置对象:
Request、response、pageContext、session、application、out、config、page、exception
四个作用域:pageContext < request < session < application
EL表达式
<body>
<%
String first = (String)request.getAttribute("first");
String second = (String)session.getAttribute("second");
String third = (String)application.getAttribute("third");
if(first == null){
first = "";
}
if(second == null){
second = "";
}
if(third == null){
third = "";
}
%>
<h1 style="color:blue;font-size:20px"><%=first %></h1>
<h1 style="color:red;font-size:25px"><%=second %></h1>
<h1 style="color:orange;font-size:30px"><%=third %></h1>
<hr>
<h1 style="color:blue;font-size:20px">${first}</h1>
<h1 style="color:red;font-size:25px">${second}</h1>
<h1 style="color:orange;font-size:30px">${third}</h1>
<hr>
<h1 style="color:blue;font-size:20px">${pageScope.first}</h1>
<h1 style="color:blue;font-size:20px">${requestScope.first}</h1>
<h1 style="color:red;font-size:25px">${sessionScope.second}</h1>
<h1 style="color:orange;font-size:30px">${applicationScope.third}</h1>
<hr>
<h1 style="color:blue;font-size:20px">el表达式获取全局初始化参数:${initParam.han }</h1>
<h1 style="color:red;font-size:25px">el表达式获取浏览器信息:${header["user-agent"] }</h1>
<h1 style="color:orange;font-size:30px">el表达式获取浏览器默认语言:${header["accept-language"] }</h1>
<hr>
el表达式获取参数列表:${pageContext.request.queryString}<br>
el表达式获取访问地址:${pageContext.request.requestURL}<br>
el表达式获取项目名称:${pageContext.request.contextPath}<br>
el表达式获取提交方式:${pageContext.request.method}<br>
el表达式获取协议名称:${pageContext.request.scheme }<br>
el表达式获取用户名称:${pageContext.request.remoteUser }<br>
el表达式获取用户地址:${pageContext.request.remoteAddr }<br>
el表达式判断当前session是否是新的:${pageContext.session.new }<br>
el表达式获取session的id:${pageContext.session.id }<br>
el表达式获取主机段服务器信息:${pageContext.servletContext.serverInfo }<br>
el表达式获取上一次访问路径:${header.referer }<br>
${pageContext.request.requestURI}<br>
${pageContext.request.remotePort }<br>
${pageContext.request.localAddr }<br>
${pageContext.request.localPort }<br>
<hr>
<%
String query = request.getQueryString();
StringBuffer url = request.getRequestURL();
String uri = request.getRequestURI();
String contextpath = request.getContextPath();
String method = request.getMethod();
String scheme = request.getScheme();
String user = request.getRemoteUser();
String addr = request.getRemoteAddr();
int port = request.getRemotePort();
String sessionid = session.getId();
String host = request.getRemoteHost();
String addr1 = request.getLocalAddr();
String useragent = request.getHeader("user-agent");
String language = request.getHeader("accept-language");
String accept = request.getHeader("accept");
String han = application.getInitParameter("han");
String referer = request.getHeader("referer");
%>
<%=query %><br>
<%=url %><br>
<%=uri %><br>
<%=method %><br>
<%=contextpath %><br>
<%=scheme %><br>
<%=user %><br>
<%=addr %><br>
<%=port %><br>
<%=sessionid %><br>
<%=host %><br>
<%=addr1 %><br>
<%=useragent %><br>
<%=language %><br>
<%=accept %><br>
<%=han %><br>
<%=referer %><br>
</body>
JSTL的导入:
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<c:choose>,<c:when>,<c:otherwise>是同时出现的一个组合,即 <c:choose>中只允许有<c:when>和 <c:otherwise>子节点,不允许有其他的标签子节点,可以允许有多个<c:when>标签,就相当于java中的if(){}else if(){}else if{}else{} 即<c:choose><c:when><c:when><c:when><c:otherwise>
<c:forEach items="" var="">其中items就是要遍历的数组 都是从作用域中获取 var就相当于该数组中的每一个变量
<%--要求:1 如果是第一张图片 那么将第一张图片链接到百度 如果是最后一张图片 链接到谷歌 其他的每行显示5张图片 --%>
<body>
<c:choose>
<c:when test="${empty list}">
<h1 style="color:blue;font-size:25px">没有图片信息</h1>
</c:when>
<c:otherwise>
<c:forEach items="${list}" var="str" varStatus="strs">
<c:if test="${strs.first}">
<a href="http://www.baidu.com"><img alt="" src="${str}" width="150px" height="150px"/></a>
</c:if>
<c:if test="${strs.last}">
<a href="http://www.google.com"><img alt="" src="${str}" width="150px" height="150px"/></a>
</c:if>
<c:if test="${!strs.first && !strs.last}">
<img alt="" src="${str}" width="150px" height="150px"/>
</c:if>
<c:if test="${strs.count % 5 == 0}"><br></c:if>
</c:forEach>
</c:otherwise>
</c:choose>
</body>
varStatus="strs"(用来存放现在指到的成员的相关信息) :strs.first第一个位置返回true,其他返回false;strs.last最后一个返回true,其他返回false;strs.count计数;strs.index索引位置
<c:forEach>标签中还有属性begin(int循环开始位置)、end(int循环结束位置)、step(int每次迭代间隔)