JSP和Servlet

目录:

  • <jsp:include>动作和<%@include%>指令
  • getAttribute与getParameter的区别
  • 解决jsp乱码问题

 

一、<jsp:include>动作和<%@include%>指令

JSP页面->转换为Servlet(.java)->编译为字节码(.class)->加载运行.class生成HTML

Servlet和JSP都是单实例的

<jsp:include>动作与<%@include%>指令的功能很相似,但也存在一些区别。

<%@include%>指令是编译阶段的指令,即,所包含文件的内容是在编译时插入到JSP文件中的。因此,如果只修改了被包含文件,但没有修改JSP页面,这时可能就不会重新编译,而是直接执行已经存在的字节码文件。因此,对于不经常修改的被包含文件,可以使用<%@include%>指令;但如果被包含文件需要经常修改,还是最好使<jsp:include>动作。另一个区别是,<jsp:include>动作使用page属性来指定被包含页面,而<%@include%>指令使用file属性来指定被包含文件。

<%@include file="相对路径的url" %>

其中,file属性指定被包含文件的相对URL,被包含文件可以不是JSP文件,可以是HTML文件或文本文件。如果file属性没有指定文件的路径信息,表明被包含文件与JSP页面位于同一目录下。

<jsp:include page="relative URL" flush="true" />

其中,page属性指定当前要包含的页面的相对路径URL。flush属性值为布尔型,默认为false,其值为true时,表示在包含资源前清空缓存。

带有参数请求的<jsp:include>动作的语法格式如下:

<jsp:include page="relative URL" flush="true">

<jsp:param name="param_name" value="param_value" />

</jsp:include> 

看来<jsp:include>动作比<%@include%>指令优越一些,因为前者能动态决定是否编译,维护上带来方便。那还有使用<%@include%>指令的必要吗?

一般来说,应该尽可能地使用<jsp:include>动作。但<%@include%>指令还是有存在意义的,例如,需要在所包含的文件中定义JSP页面要用到的变量或方法时,只能使用<%@include%>指令。

例如,被包含页面为include.jsp,某文件内容只是定义了一个num变量:

<%! int num=0;%>

在JSP文件中,使用<%@include%>指令进行包含。这时,不能使用<jsp:include>动作,否则在下一句JSP表达式会报错。因为未定义num变量,不能转换成Servlet。

包含include.jsp的JSP文件内容如下:

<html>

  <body>

    <%@ include file="include.jsp" %>

    <%= num %>

  </body>

</html>

不同有效范围中的setAttribute()方法

有效范围                                    Servlet调用方式                                              JSP调用方式

应用有效   getServletContext().setAttribute("name",value);      application.setAttribute("name",value);

会话有效   requset.getSession.setAttribute("name",value);       session.setAttribute("name",value);

请求有效   request.setAttribute("name",value);                       request.setAttribute("name",value);

页面有效   没有对应方法                                                       pageContext.setAttribute("name",value);

 

二、getAttribute与getParameter的区别

getAttribute表示从request范围取得设置的属性,必须要先setAttribute设置属性,才能通过getAttribute来取得,设置与取得的为Object对象类型 
getParameter表示接收参数,参数为页面提交的参数,包括:表单提交的参数、URL重写(就是xxx?id=1中的id)传的参数等,因此这个并没有设置参数的方法(没有setParameter),而且接收参数返回的不是Object,而是String类型

HttpServletRequest类既有getAttribute()方法,也由getParameter()方法,这两个方法有以下区别:

(1)HttpServletRequest类有setAttribute()方法,而没有setParameter()方法

(2)当两个Web组件之间为链接关系时,被链接的组件通过getParameter()方法来获得请求参数,例如假定welcome.jsp和authenticate.jsp之间为链接关系,welcome.jsp中有以下代码:

<a  href="authenticate.jsp?username=weiqin">authenticate.jsp  </a>

或者:

<form  name="form1"  method="post"  action="authenticate.jsp">
   请输入用户姓名:<input  type="text"  name="username">
   <input  type="submit"  name="Submit"  value="提交">
</form>

在authenticate.jsp中通过request.getParameter("username")方法来获得请求参数username:

<%  String  username=request.getParameter("username");  %>

(3)当两个Web组件之间为转发关系时,转发目标组件通过getAttribute()方法来和转发源组件共享request范围内的数据。假定  authenticate.jsp和hello.jsp之间为转发关系。authenticate.jsp希望向hello.jsp传递当前的用户名字,  如何传递这一数据呢?先在authenticate.jsp中调用setAttribute()方法:

<%
    String  username=request.getParameter("username");
    request.setAttribute("username",username);
%>
<jsp:forward  page="hello.jsp"  />

在hello.jsp中通过getAttribute()方法获得用户名字:

<%  String  username=(String)request.getAttribute("username");  %>
Hello:  <%=username  %>

从更深的层次考虑,request.getParameter()方法传递的数据,会从Web客户端传到Web服务器端,代表HTTP请求数据。request.getParameter()方法返回String类型的数据。

request.setAttribute()和getAttribute()方法传递的数据只会存在于Web容器内部,在具有转发关系的Web组件之间共享。这两个方法能够设置Object类型的共享数据。

request.getParameter()取得是通过容器的实现来取得通过类似post,get等方式传入的数据,,  request.setAttribute()和getAttribute()只是在web容器内部流转,仅仅是请求处理阶段,这个的确是正解.

getAttribute是返回对象,getParameter返回字符串

request.getAttribute()方法返回request范围内存在的对象,而request.getParameter()方法是获取http提交过来的数据。

 

三、jsp页面乱码

JSP编程中网页显示出现乱码的情况,基本可以归为5类:

1. JSP页面显示乱码。

2. Servlet接收Form/Request传递的参数时显示为乱码

3. JSP接收Form/Request传递的参数时显示为乱码

4. 用<jsp:forward page="catalog2.html"></jsp:forward>时页面显示乱码

5. 数据库存取的时候产生乱码。

 

解决方法:

1. JSP页面显示乱码。

第一种为在页面的开头加上:

<%@ page language="java" contentType="text/html; charset=GBK" pageEncoding="GBK"%>

注:有时候如果不再页面开头加上这句,则页面中无法保存中文字符,并提示:中文字符在不能被iso-8859-1字符集mapped,这是由于默认情况下,JSP是用iso-8859-1来编码的,可以在Window->Preferences->General->Content Type选项下,在右边的窗口选择Text->Jsp,然后在下面的Default Encoding由默认的iso-8859-1改为GBK,然后点击update即可解决。

然而这种方式会带来一些问题:由于这一句在其他文件include该文件的时候不能被继承,所以include它的文件也需要在文件开头加上这句话,此时如果用的是pageEncoding="gbk"则会出现问题。类似于org.apache.jasper.JasperException: /top.jsp(1,1) Page directive: illegal to have multiple occurrences of contentType with different values (old: text/html;charset=GBK, new: text/html;charset=gbk).

类似地,如果两个文件一个用的是gbk,一个用的是gb2312也会出现问题。

另一种更好的解决方式为:

在项目的web.xml中添加以下片段:

<jsp-config>

<jsp-property-group>

<description>

Special property group for JSP Configuration JSP example.

</description>

<display-name>JSPConfiguration</display-name>

<url-pattern>*.jsp</url-pattern>

<el-ignored>true</el-ignored>

<page-encoding>GBK</page-encoding>

<scripting-invalid>false</scripting-invalid>

<include-prelude></include-prelude>

<include-coda></include-coda>

</jsp-property-group>

<jsp-property-group>

<description>

Special property group for JSP Configuration JSP example.

</description>

<display-name>JSPConfiguration</display-name>

<url-pattern>*.html</url-pattern>

<el-ignored>true</el-ignored>

<page-encoding>GBK</page-encoding>

<scripting-invalid>false</scripting-invalid>

<include-prelude></include-prelude>

<include-coda></include-coda>

</jsp-property-group>

</jsp-config>

2. Servlet接收Form/Request传递的参数时显示为乱码的解决方式:

第一种解决方式为在用到request方法的前面加上这条语句:

request.setCharacterEncoding("GBK");

同样地,这也会由于页面设置中GbK或gB2312大小写不同或者采用不同的汉语字符集而发生错误。

另一种更好的解决方式为:添加一个名为SetCharacterEncodingFilter的filter。

filter的源文件为(参见apach安装目录下\webapps\jsp-examples\WEB-INF\classes\filters中的SetCharacterEncodingFilter.java文件):

package com.filters;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;

import javax.servlet.UnavailableException;

public class SetCharacterEncodingFilter implements Filter {

protected String encoding = null;

protected FilterConfig filterConfig = null;

protected boolean ignore = true;

public void destroy() {

this.encoding = null;

this.filterConfig = null;

}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain)

throws IOException, ServletException {

// Conditionally select and set the character encoding to be used

if (ignore || (request.getCharacterEncoding() == null)) {

String encoding = selectEncoding(request);

if (encoding != null)

request.setCharacterEncoding(encoding);

}

// Pass control on to the next filter

chain.doFilter(request, response);

}

public void init(FilterConfig filterConfig) throws ServletException {

this.filterConfig = filterConfig;

this.encoding = filterConfig.getInitParameter("encoding");

String value = filterConfig.getInitParameter("ignore");

if (value == null)

this.ignore = true;

else if (value.equalsIgnoreCase("true"))

this.ignore = true;

else if (value.equalsIgnoreCase("yes"))

this.ignore = true;

else

this.ignore = false;

}

protected String selectEncoding(ServletRequest request) {

return (this.encoding);

}

}

同时在web.xml中添加一下片段:

<filter>

<filter-name>SetCharacterEncoding</filter-name>

<filter-class>com.filters.SetCharacterEncodingFilter</filter-class>

<init-param>

<param-name>encoding</param-name>

<param-value>GBK</param-value>

</init-param>

</filter>

<filter-mapping>

<filter-name>SetCharacterEncoding</filter-name>

<url-pattern>/*</url-pattern>

</filter-mapping>

3. JSP接收Form/Request传递的参数时显示为乱码

当我们按照第二种乱码的解决方式修改了web.xml并添加了filter之后,有时候并不一定就对乱码问题高枕无忧了,有时候我们会奇怪的发现Sevlet接收Form/Request传递的参数可以正常显示了,但是jsp页面接受Form/Request传递的参数却仍然显示为乱码。这是为什么呢?

对于我遇到的情况而言,我发现是由于我在用Form发送信息的页面采用了这样的html:

<form action="getParam.jsp" >

姓名<input type="text" name ="UserName"> <br>

选出你喜欢吃的水果:

<input type ="checkbox" name = "checkbox1" value = "苹果"> 苹果

<input type ="checkbox" name = "checkbox1" value = "西瓜"> 西瓜

<input type ="checkbox" name = "checkbox1" value = "桃子"> 桃子

<input type ="checkbox" name = "checkbox1" value = "葡萄"> 葡萄

<input type = "submit" value = "提交">

</form>

也就是说没有指定form的method属性。而问题就发生在此,Form的默认mothod属性为get.

而get是通过在发送请求的url后面加?然后加参数和值来传递数据的的,编码格式为ASCII.这就要求我们在传递的数据中有非ASCII字符或是超过了100个字符,那么你必须使用method="post",否则就会出现乱码。

所以解决方式为:第二种乱码的解决方式+在发送页面的Form中指定method为post.

4. 用<jsp:forward page="catalog2.html"></jsp:forward>时页面显示乱码的解决方式

此时实际上乱码的原因和产生其他几种乱码的原因不同,它的原因在于我们用eclipse编辑要forward的html或者jsp文件时,采用的编码是可以产生中文乱码的编码而不是GBK或者GB2312.所以解决方式就是把eclipse编辑器的编码方式改为GBK或者GB2312.

具体操作方式见:上文红色字体部分。

5. 数据库存取的时候产生乱码的解决方式

当然,在写数据库时,也要保正数据库的编码与其它一致:

我们可以在系统盘windows目录下的my.ini文件,在文件中插入一行default-character-set=GBK,但上面说了这么多,大家也应该明白些了吧,改动太多的默认设置不是我的风格,因此上,这一行还是不要加的好。

但不管怎么样,我们还是要创建一个基于中文编码的数据库,当然,用客户端登录的时候,某些客户用自动把字体编码转换成中文编码。在这里,我想说一下在DOS下创建中文编码数据库的方法:

在进入数据库的时候,用mysql --default-character-set=gbk -u root -p 这句话进入mysql,然后创建数据库,如:create database admin;这样创建起来的数据库就是基于中文编码的了。

用连接数据库的时候,读出的数据也可能是乱码,解决这个问题的方法非常简单,只要在你建立数据库连接的时候把URL设置成下面这个样子就可以了:URL= jdbc:mysql://localhost:3306/my_database?useUnicode=true&characterEncoding=GBK

最后总结,把各种地方的编码统一起来,所在的乱码问题就都解决了。

转载于:https://my.oschina.net/u/3450072/blog/886972

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值