您的位置:首页 > 编程语言 > Java开发

Java Servlet 开发常用代码、模板、问题

2016-03-17 17:30 483 查看

一 空Servlet类模板

import java.io.IOException;

mport java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

public class ServletDemo1 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

}

}

二 web.xml配置

<servlet>

<servlet-name>ServletDemo1</servlet-name>

<servlet-class>xxx.yyy.zzz.ServletDemo1</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>ServletDemo1</servlet-name>

<url-pattern>/servlet/ServletDemo1</url-pattern>

</servlet-mapping>

<servlet-mapping>

<servlet-name>ServletDemo1</servlet-name>

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

</servlet-mapping>

/abc/*

/*

/abc

*.do

<servlet>

<servlet-name>invoker</servlet-name>

<servlet-class>

org.apache.catalina.servlets.InvokerServlet

</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

如果某个Servlet的映射路径仅仅为一个正斜杠(/),那么这个Servlet就成为当前Web应用程序的缺省Servlet。

凡是在web.xml文件中找不到匹配的<servlet-mapping>元素的URL,它们的访问请求都将交给缺省Servlet处理,

<servlet>

<servlet-name>ServletDemo2</servlet-name>

<servlet-class>xxx.yyy.zzz.ServletDemo2</servlet-class>

<load-on-startup>1</load-on-startup>

</servlet>

<!-- 将ServletDemo2配置成缺省Servlet -->

<servlet-mapping>

<servlet-name>ServletDemo2</servlet-name>

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

</servlet-mapping>

在<tomcat的安装目录>\conf\web.xml文件中,注册了一个名称为org.apache.catalina.servlets.DefaultServlet的Servlet,并将这个Servlet设置为了缺省Servlet。

三 Servlet的线程安全问题

  当多个客户端并发访问同一个Servlet时,web服务器会为每一个客户端的访问请求创建一个线程,并在这个线程上调用Servlet的service方法,因此service方法内如果访问了同一个资源的话,就有可能引发线程安全问题。

不存在线程安全问题的代码:

public class ServletDemo3 extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

/**

* i变量被多个线程并发访问,但是没有线程安全问题,因为i是doGet方法里面的局部变量,

* 当有多个线程并发访问doGet方法时,每一个线程里面都有自己的i变量,

* 各个线程操作的都是自己的i变量,所以不存在线程安全问题

* 多线程并发访问某一个方法的时候,如果在方法内部定义了一些资源(变量,集合等)

* 那么每一个线程都有这些东西,所以就不存在线程安全问题了

*/

int i=1;

i++;

response.getWriter().write(i);

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

存在线程安全问题的代码:

public class ServletDemo3 extends HttpServlet {

int i=1;

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

i++;

try {

Thread.sleep(1000*4);

} catch (InterruptedException e) {

e.printStackTrace();

}

response.getWriter().write(i+"");

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

  把i定义成全局变量,当多个线程并发访问变量i时,就会存在线程安全问题了;同时开启两个浏览器模拟并发访问同一个Servlet,本来正常来说,第一个浏览器应该看到2,而第二个浏览器应该看到3的,结果两个浏览器都看到了3。

如何解决?

public class ServletDemo3 extends HttpServlet {

int i=1;

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

/**

* 加了synchronized后,并发访问i时就不存在线程安全问题了,

* 假如现在有一个线程访问Servlet对象,那么它就先拿到了Servlet对象的那把锁

* 等到它执行完之后才会把锁还给Servlet对象,由于是它先拿到了Servlet对象的那把锁,

* 所以当有别的线程来访问这个Servlet对象时,由于锁已经被之前的线程拿走了,后面的线程只能排队等候了

*

*/

synchronized (this) {//在java中,每一个对象都有一把锁,这里的this指的就是Servlet对象

i++;

try {

Thread.sleep(1000*4);

} catch (InterruptedException e) {

e.printStackTrace();

}

response.getWriter().write(i+"");

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request, response);

}

}

  现在这种做法是给Servlet对象加了一把锁,保证任何时候都只有一个线程在访问该Servlet对象里面的资源,这样就不存在线程安全问题了

这种做法虽然解决了线程安全问题,但是编写Servlet却不能用这种方式处理线程安全问题,假如有9999个人同时访问这个Servlet,那么这9999个人必须按先后顺序排队轮流访问。

  针对Servlet的线程安全问题,Sun公司提供有解决方案的:让Servlet去实现一个SingleThreadModel接口,如果某个Servlet实现了SingleThreadModel接口,那么Servlet引擎将以单线程模式来调用其service方法。

  查看Sevlet的API可以看到,SingleThreadModel接口中没有定义任何方法和常量,在Java中,把没有定义任何方法和常量的接口称之为标记接口,经常看到的一个最典型的标记接口就是"Serializable",这个接口也是没有定义任何方法和常量的,标记接口在Java中有什么用呢?主要作用就是给某个对象打上一个标志,告诉JVM,这个对象可以做什么,比如实现了"Serializable"接口的类的对象就可以被序列化,还有一个"Cloneable"接口,这个也是一个标记接口,在默认情况下,Java中的对象是不允许被克隆的,就像现实生活中的人一样,不允许克隆,但是只要实现了"Cloneable"接口,那么对象就可以被克隆了。

  让Servlet实现了SingleThreadModel接口,只要在Servlet类的定义中增加实现SingleThreadModel接口的声明即可。

  对于实现了SingleThreadModel接口的Servlet,Servlet引擎仍然支持对该Servlet的多线程并发访问,其采用的方式是产生多个Servlet实例对象,并发的每个线程分别调用一个独立的Servlet实例对象。

  实现SingleThreadModel接口并不能真正解决Servlet的线程安全问题,因为Servlet引擎会创建多个Servlet实例对象,而真正意义上解决多线程安全问题是指一个Servlet实例对象被多个线程同时调用的问题。事实上,在Servlet API 2.4中,已经将SingleThreadModel标记为Deprecated(过时的)。

四 常用功能代码

1 hello world

public void init() throws ServletException

{

message = "Hello World";

}

public void doGet(HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException

{

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<h1>" + message + "</h1>");

}

2 在客户端输出一个html文档

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");

out.println("<HTML>");

out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");

out.println(" <BODY>");

out.print(" This is ");

out.print(this.getClass());

out.println(", using the GET method");

out.println(" </BODY>");

out.println("</HTML>");

out.flush();

out.close();

3 处理用户登陆的servlet实现方法

Login.java

package com.bai;

import javax.servlet.http.*;

import java.io.*;

public class Login extends HttpServlet{

public void doGet(HttpServletRequest req,HttpServletResponse res){

try{req.setCharacterEncoding("gb2312");

res.setContentType("text/html;charset=gb2312");

PrintWriter pw=res.getWriter();

pw.println("<html>");

pw.println("<body>");

pw.println("<h1>登陆界面</h1>");

pw.println("<form action=logincl method=post>");

pw.println("用户名:<input type=text name=username><br>");

pw.println("密码:<input type=password name=passwd><br>");

pw.println("<input type=submit value=login><br>");

pw.println("</form>");

pw.println("</body>");

pw.println("</html>");

}

catch(Exception e){

e.printStackTrace();

}

}

public void doPost(HttpServletRequest req,HttpServletResponse res){

this.doGet(req,res);

}

}

LoginCl.java

package com.bai;

import javax.servlet.http.*;

import java.io.*;

import java.sql.*;

public class LoginCl extends HttpServlet{

public void doGet(HttpServletRequest req,HttpServletResponse res){

Connection conn=null;

Statement stmt=null;

ResultSet rs=null;

String sql = "select username,passwd from users where username = ? and passwd = ?";

try{//req.setCharacterEncoding("gb2312");

String user=req.getParameter("username");

String password=req.getParameter("passwd");

Class.forName("com.mysql.jdbc.Driver");

conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/sqdb","root","root");

// stmt=conn.createStatement();

PreparedStatement pstmt = conn.prepareStatement(sql);

pstmt.setString(1, user);

pstmt.setString(2, password);

rs = pstmt.executeQuery();

// rs=stmt.executeQuery("select top 1 * from users where username='"+user

// +"' and passwd='"+password+"'");

if(rs.next())

{

HttpSession hs=req.getSession(true);

hs.setMaxInactiveInterval(60);

hs.setAttribute("name",user);

res.sendRedirect("welcome?&uname="+user+"&upass="+password);

}

else{

res.sendRedirect("login"); //url

}

}

catch(Exception e){

e.printStackTrace();

}finally{

try{

if(rs!=null){

rs.close();

}

if(stmt!=null){

stmt.close();

}

if(conn!=null){

conn.close();

}

}catch(Exception e){

e.printStackTrace();

}

}

}

public void doPost(HttpServletRequest req,HttpServletResponse res){

this.doGet(req,res);

}

}

注:

上面这个处理用户名密码带有明显注入漏洞,可以根据用户名从数据库取密码,用取出的密码和用户输入的密码比较

sql=select passwd from users where username = ? limit 1

if(rs.next())

{

String passwd=rs.getString(1);

if(passwd.equals(password))

//密码正确

else //密码错误

}

Welcome.java

package com.bai;

import javax.servlet.http.*;

import java.io.*;

public class Welcome extends HttpServlet{

public void doGet(HttpServletRequest req,HttpServletResponse res){

HttpSession hs=req.getSession();

String val=(String)hs.getAttribute("pass");

if(val==null){

try{

System.out.print(1);

res.sendRedirect("login");

}catch(Exception e){

e.printStackTrace();

}

}

String u=req.getParameter("uname");

String p=req.getParameter("upass");

try{//req.setCharacterEncoding("gb2312");

PrintWriter pw=res.getWriter();

pw.println("welcome! "+u+"&pass="+p);

}

catch(Exception e){

e.printStackTrace();

}

}

public void doPost(HttpServletRequest req,HttpServletResponse res){

this.doGet(req,res);

}

}

4 servlet中session

在servlet中,session是封装在javax.servlet.http.HttpSession这个接口中的,这个接口是构建在cookie或者URL重写的基础上,要得到一个HttpSession的实例,就可以通过HttpServletRequest的getSession()方法来获得

HttpServletRequest有两个重载的getSession()方法,一个接受一个boolean的类型的值,另一个不带任何参数,getSession()方法和getSession(true)方法功能一样,就是如果对应的客户端已经产生过一个session,那么就会返回这个旧的session,否则,这个方法将会产生一个session ID并且和对应的客户端绑定在一起,而如果getSession(false)表示如果对应的客户端已经有对应的session,那么返回这个旧的session,否则不会产生新的session。可以使用HttpSession对象上的isNow()方法来判定这个session是否为新建的

HttpSession常用方法

public void setAttribute(String name,Object value)

将value对象以name名称绑定到会话

public object getAttribute(String name)

取得name的属性值,如果属性不存在则返回null

public void removeAttribute(String name)

从会话中删除name属性,如果不存在不会执行,也不会抛处错误.

public Enumeration getAttributeNames()

返回和会话有关的枚举值

public void invalidate()

使会话失效,同时删除属性对象

public Boolean isNew()

用于检测当前客户是否为新的会话

public long getCreationTime()

返回会话创建时间

public long getLastAccessedTime()

返回在会话时间内web容器接收到客户最后发出的请求的时间

public int getMaxInactiveInterval()

返回在会话期间内客户请求的最长时间为秒

public void setMaxInactiveInterval(int seconds)

允许客户客户请求的最长时间

ServletContext getServletContext()

返回当前会话的上下文环境,ServletContext对象可以使Servlet与web容器进行通信

public String getId()

返回会话期间的识别号

一个保存信息到session的例子

sessionlogin.html

<meta name="keywords" content="keyword1,keyword2,keyword3" />

<meta name="description" content="this is my page" />

<meta name="content-type" content="text/html; charset=UTF-8" />

<!-- <link rel="stylesheet" type="text/css" href="./styles.css">--></pre>

<form action="servlet/saveinfo" method="post">

用户名:

<input type="text" name="username" /> <input type="submit" />

密码:

<input type="password" name="userpasswd" />

</form>

<pre>

</pre>

</div>

<div>

package xxx;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

public class saveinfo extends HttpServlet {

public saveinfo() {

super();

}

public void destroy() {

super.destroy(); // Just puts "destroy" string in log

// Put your code here

}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

//如果用户输入过了用户名 则将其放在session中

if(request.getParameter("username")!=null);

{

HttpSession session = request.getSession();

session.setAttribute("username",request.getParameter("username"));

}

response.setContentType("text/html;charset=GBK");

PrintWriter out = response.getWriter();

out.println("session已经创建");

out.println("

");

out.println("跳转到其他<a>页面</a>");

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request,response);

}

public void init() throws ServletException {

// Put your code here

}

}

package xxx;

import java.io.IOException;

import java.io.PrintWriter;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpSession;

public class getsession extends HttpServlet {

public getsession() {

super();

}

public void destroy() {

super.destroy(); // Just puts "destroy" string in log

// Put your code here

}

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html;charset=GBK");

PrintWriter out = response.getWriter();

String username = "";

//此处不是创建session 而是去取已经创建的session

HttpSession session = request.getSession();

//如果已经取到,说明已经登录

if(session!=null)

{

username = (String)session.getAttribute("username");

out.println("获得创建的Session");

out.println("

");

out.println("登录名:"+username);

}

else

{

response.sendRedirect("../sessionlogin.html");

}

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

doGet(request,response);

}

public void init() throws ServletException {

// Put your code here

}

}

5 获得客户端IP和url

可以配合实现IP白名单控制,

import javax.servlet.http.HttpServletRequest;

public class ClientInfoUtil{

/**

* 获得客户端的IP地址

* @param request

* @return

*/

static public String getIP(HttpServletRequest request) {

String ip = request.getHeader("x-forwarded-for");

if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

ip = request.getHeader("Proxy-Client-IP");

}

if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

ip = request.getHeader("WL-Proxy-Client-IP");

}

if(ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {

ip = request.getRemoteAddr();

}

return ip;

}

/**

* 获得客户端访问服务器的url地址

* @param request

* @return

*/

static public String getURL(HttpServletRequest request) {

String url = request.getScheme()+"://";

url+=request.getHeader("host");

url+=request.getRequestURI();

if(request.getQueryString()!=null) {

url+="?"+request.getQueryString();

}

return url;

}

}

6 JSP+Servlet+JavaBean实现登录

登录页面:login.html

登录成功欢迎页面:login_success.jsp

登录失败页面:login_failure.jsp

Servlet处理文件:LoginServlet.java

登录页面:login.html

<!-- 一个简单的登录界面 --><!-- 该JSP程序是用来测试与MySQL数据库的连接, 需要一个数据库:LearnJSP,和其中一个表:userinfo 表中有两个字段分别为:UserName varchar (20) not null,UserPwd varchar (20) not null--><html> <head> <title>登录</title> <meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta http-equiv="Content-Language" content="ch-cn"> </head> <body> <!-- Form 用来提取用户填入并提交的信息--> <form method="post" name="frmLogin" action="LoginServlet"> <h1 align="center">用户登录</h1><br> <div align="center">用户名: <input type="text" name="txtUserName"
value="Your name" size="20" maxlength="20" onfocus="if(this.value=='Your name')this.value='';"><br>密码: <input type="password" name="txtPassword" value="Your password" size="20" maxlength="20" onfocus="if(this.value=='Your password')this.value='';"><br>
<input type="submit" name="Submit" value="提交" onClick="validateLogin();" > <input type="reset" name="Reset" value="重置"><br> </div> </form> <!-- javaScript 函数 validateLogin(),用来验证用户名和密码是否为空 --> <script language="javaScript"> function validateLogin()
{ var sUserName = document.frmLogin.txtUserName.value; var sPassword = document.frmLogin.txtPassword.value; if( sUserName=="" ) { alert("请输入用户名!"); return false; } if( sPassword=="" ) { alert("请输入密码!"); return false; } } </script>
</body></html>

登录成功欢迎页面:login_success.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>My JSP 'login_failure.jsp' starting page</title> <meta http-equiv="content-type" content="text/html;
charset=UTF-8"> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This
is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% String userName = (String)session.getAttribute ( "UserName" ); %> <div align=center> <%=userName%> 欢迎您,登录成功! </div> </body></html>

登录失败页面:login_failure.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>My JSP 'login_failure.jsp' starting page</title> <meta http-equiv="content-type" content="text/html;
charset=UTF-8"> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This
is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <% String userName = (String)session.getAttribute ( "UserName" ); %> <div align=center> <%=userName%> 对不起,登录失败! </div> </body></html>

Servlet处理文件:LoginServlet.java

/** * 该JSP程序是用来测试与MySQL数据库的连接, * 需要一个数据库:LearnJSP,和其中一个表:userinfo * 表中有两个字段分别为:UserName varchar (20) not null,UserPwd varchar (20) not null */package zieckey.login.servlet;import java.sql.Statement;import java.io.IOException;import java.sql.DriverManager;import
java.sql.ResultSet;import java.sql.SQLException;import javax.servlet.Servlet;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class
LoginServlet extends HttpServlet implements Servlet{ public LoginServlet () { // TODO Auto-generated constructor stub } /* * (non-Javadoc) * * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse)
*/ @Override protected void doGet ( HttpServletRequest arg0, HttpServletResponse arg1 ) throws ServletException, IOException { } /* * (non-Javadoc) * * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse)
*/ @Override protected void doPost ( HttpServletRequest request, HttpServletResponse response ) throws ServletException, IOException { response.setContentType ( "text/html" ); String result = ""; // 获取用户名 String sUserName = request.getParameter ( "txtUserName"
); if ( sUserName == "" || sUserName == null || sUserName.length ( ) > 20 ) { try { result = "请输入用户名(不超过20字符)!"; request.setAttribute ( "ErrorUserName", result ); response.sendRedirect ( "login.html" ); } catch ( Exception e ) { } } // 获取密码 String
sPasswd = request.getParameter ( "txtPassword" ); if ( sPasswd == "" || sPasswd == null || sPasswd.length ( ) > 20 ) { try { result = "请输入密码(不超过20字符)!"; request.setAttribute ( "ErrorPassword", result ); response.sendRedirect ( "login.html" ); } catch
( Exception e ) { } } // 登记JDBC驱动程序 try { Class.forName ( "org.gjt.mm.mysql.Driver" ).newInstance ( ); } catch ( InstantiationException e ) { // TODO Auto-generated catch block e.printStackTrace ( ); System.out.println ("InstantiationException"); } catch
( IllegalAccessException e ) { // TODO Auto-generated catch block e.printStackTrace ( ); System.out.println ("IllegalAccessException"); } catch ( ClassNotFoundException e ) { // TODO Auto-generated catch block e.printStackTrace ( ); System.out.println
("ClassNotFoundException"); } // 连接参数与Access不同 String url = "jdbc:mysql://localhost/LearnJSP"; // 建立连接 java.sql.Connection connection = null; Statement stmt = null; ResultSet rs = null; try { connection = DriverManager.getConnection ( url, "root", "011124"
); stmt = connection.createStatement ( ); // SQL语句 String sql = "select * from userinfo where username='" + sUserName + "' and userpwd = '" + sPasswd + "'"; rs = stmt.executeQuery ( sql );// 返回查询结果 } catch ( SQLException e ) { // TODO Auto-generated
catch block e.printStackTrace ( ); } try { if ( rs.next ( ) )// 如果记录集非空,表明有匹配的用户名和密码,登陆成功 { // 登录成功后将sUserName设置为session变量的UserName // 这样在后面就可以通过 session.getAttribute("UserName") 来获取用户名, // 同时这样还可以作为用户登录与否的判断依据 request.getSession ( ).setAttribute (
"UserName", sUserName ); response.sendRedirect ( "login_success.jsp" ); } else { // 否则登录失败 //response.sendRedirect ( "MyJsp.jsp" ); response.sendRedirect ( "login_failure.jsp" ); } } catch ( SQLException e ) { // TODO Auto-generated catch block e.printStackTrace
( ); } try { if ( null!=rs ) { rs.close ( ); } if ( null!=stmt ) { stmt.close ( ); } if ( null!=connection ) { connection.close ( ); } } catch ( SQLException e ) { // TODO Auto-generated catch block e.printStackTrace ( ); } } /** * */ private
static final long serialVersionUID = 1L;}

7 java servlet页面跳转

response.sendRedirect("/a.jsp");

response.sendRedirect("http://www.jb51.net");

RequestDispatcher dispatcher = request.getRequestDispatcher("/a.jsp");

dispatcher .forward(request, response);

response.setHeader("Location","");

8 java中Servlet处理乱码

1)从页面获取数据的servlet出现乱码,在servlet中已经把request.setCharacterEncoding("GB2312");加入到代码中去,

JAVA是Unicode编码,先转换成ISO8859-1,然后再转换成GBK或是GB2312.

request.setCharacterEncoding("ISO8859-1");

ad=request.getParameter("name");

byte[] temp3 = ad.getBytes("GBK");

String str = new String(temp3);

这样就是中文啦

2)直接在服务器里设置编码转换

在Tomcat的conf目录里找到SERVER.XML文件,设置如下:

里面增加一个属性,URIEncoding="GBK"

3)JSP页面上是中文,但是看的后是乱码

解决的办法就是在JSP页面的编码的地方,因为Jsp转成Java文件时的编码问题,默认的话有的服务器是ISO-8859-1,如果一个JSP中直接输入了中文,Jsp把它当作 ISO8859-1来处理是肯定有问题的,这一点,我们可以通过查看Jasper所生成的Java中间文件来确认

4)当用Request对象获取客户提交的汉字代码的时候,会出现乱码

解决的办法是:要配置一个filter,也就是一个Servelet的过滤器,

代码如下:

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain)throws IOException, ServletException {

request.setCharacterEncoding("GBK");

// 传递控制到下一个过滤器

chain.doFilter(request, response);

}

配置web.xml

<filter></filter>

<filter-name></filter-name>Set Character Encoding

<filter-class></filter-class>SetCharacterEncodingFilter

<filter-mapping></filter-mapping>

<filter-name></filter-name>Set Character Encoding

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

如果还是出现这种情况的话就往下看看是不是出现了第四种情况,Form提交的数据是不是用get提交的,一般来说用post提交的话是没有问题的,如果是的话,看第四种解决的办法。

还有就是对含有汉字字符的信息进行处理,处理的代码是:

public String toUni(String gbStr){

String uniStr = "";

if(gbStr == null){

gbStr = "";

}

try{

byte[] tempByte = gbStr.getBytes("GB2312");

uniStr = new String(tempByte,"ISO8859_1");

}catch(Exception ex){

}

return uniStr;

}

}

也可以在直接的转换,首先将获取的字符串用ISO-8859-1进行编码,然后将这个编码存放到一个字节数组中,然后将这个数组转化成字符串对象就可以了,

String str=request.getParameter(“girl”);

Byte B[]=str.getBytes(“ISO-8859-1”);

Str=new String(B);

通过上述转换的话,提交的任何信息都能正确的显示。

5)在 Form get请求在服务端用request. getParameter(“name”)时返回的是乱码

按tomcat的做法设置Filter也没有用或者用 request.setCharacterEncoding("GBK");也不管用问题是出在处理参数传递的方法上:如果在servlet中用 doGet(HttpServletRequest request, HttpServletResponse response)方法进行处理的话前面即使是写了:

request.setCharacterEncoding("GBK");

response.setContentType("text/html;charset=GBK");

也是不起作用的,返回的中文还是乱码.

如果把这个函数改成doPost(HttpServletRequest request, HttpServletResponse response)一切就OK了。

同样,在用两个JSP页面处理表单输入之所以能显示中文是因为用的是post方法传递的,改成get方法依旧不行。

由此可见在servlet中用doGet()方法或是在JSP中用get方法进行处理要注意。这毕竟涉及到要通过浏览器传递参数信息,很有可能引起常用字符集的冲突或是不匹配。

这个地方理解为request.setCharacterEncoding("GBK");set的是request中的body,而不是header部分,get请求时把参数放在url后边,不是放在body中,所以这个时候request.setCharacterEncoding("GBK")就没有起到作用,换到post提交就没有问题了,

解决的办法是:

1) 打开tomcat的server.xml文件,找到区块,加入如下一行:

URIEncoding=”GBK”

完整的应如下:

<connector uriencoding="GBK" maxthreads="150" debug="0" redirectport="8443" port="8080" enablelookups="false" maxsparethreads="75" minsparethreads="25" connectiontimeout="20000" disableuploadtimeout="true" acceptcount="100"></connector>

重启tomcat,一切OK。

6)JSP页面上有中文,按钮上面也有中文,但是通过服务器查看页面的时候出现乱码

解决的办法是:首先在JSP文件中不应该直接包含本地化的消息文本,而是应该通过<bean:message>标签从Resource Bundle中获得文本。应该把中文文本放到Application.properties文件中,这个文件放在WEB-INF/classes/* 下,例如页面里有姓名,年龄两个label,首先就是要建一个Application.properties,里面的内容应该是name=”姓名” age=”年龄”,然后把这个文件放到WEB-INF/classes/properties/下,接下来根据
Application.properties文件,对他进行编码转化,创建一个中文资源文件,假定名字是 Application_cn.properties。在JDK中提供了native2ascii命令,能够实现字符编码的转换。在DOS环境中找到你放置Application.properties的这个文件的目录,在DOS环境中执行一下命令,将生成按GBK编码的中文资源文件 Application_cn.properties:native2ascii ?encoding gbk Application.properties
Application_cn.properties执行以上命令以后将生成如下内容的Application_cn.properties文件: name=u59d3u540d age=u5e74u9f84,在Struts-config.xml中配置:<message-resources parameter="properties.Application_cn"></message-resources>。到这一步,基本上完成了一大半,接着就要在JSP页面上写,到名字的那个label是要写<bean:message
key="”name”">,这样的化在页面上出现的时候就会出现中文的姓名,年龄这个也是一样,按钮上汉字的处理也是同样的。

7)写入到数据库是乱码

解决的方法:要配置一个filter,也就是一个Servelet的过滤器,代码如同第二种时候一样。

如果是通过JDBC直接链接数据库的时候,配置的代码如下:jdbc:mysql://localhost:3306/workshopdb? useUnicode=true&characterEncoding=GBK,这样保证到数据库中的代码是不是乱码。

如果是通过数据源链接的话不能按照这样的写法了,首先就要写在配置文件中,

<context debug="0" path="/workshop" docbase="workshop"></context>reloadable="true" >

<resource name="jdbc/WorkshopDB"></resource>auth="Container"

type="javax.sql.DataSource" />

<resourceparams name="jdbc/WorkshopDB"></resourceparams>

<parameter></parameter>

<name></name>factory

<value></value>org.apache.commons.dbcp.BasicDataSourceFactory

<parameter></parameter>

<name></name>maxActive

<value></value>100

<parameter></parameter>

<name></name>maxIdle

<value></value>30

<parameter></parameter>

<name></name>maxWait

<value></value>10000

<parameter></parameter>

<name></name>username

<value></value>root

<parameter></parameter>

<name></name>password

<value></value>

<parameter></parameter>

<name></name>driverClassName

<value></value>com.mysql.jdbc.Driver

<parameter></parameter>

<name></name>url

<value></value>

8)servlet分页

Oracle数据库,获取SCOTT用户EMP表中的数据,

创建一个对象 UserData,用以保存从数据库中获取的数据。

package com.tool;

import java.math.BigDecimal;

import java.util.Date;

public class UserData {

/**

* EMP表中的数据属性

*/

private String ename;

private String job;

private BigDecimal empno;

private BigDecimal mgr;

private Date hireDate;

private BigDecimal sal;

private BigDecimal comm;

private BigDecimal deptno;

public BigDecimal getEmpno() {

return empno;

}

public void setEmpno(BigDecimal empno) {

this.empno = empno;

}

public BigDecimal getMgr() {

return mgr;

}

public void setMgr(BigDecimal mgr) {

this.mgr = mgr;

}

public Date getHireDate() {

return hireDate;

}

public void setHireDate(Date hireDate) {

this.hireDate = hireDate;

}

public BigDecimal getSal() {

return sal;

}

public void setSal(BigDecimal sal) {

this.sal = sal;

}

public BigDecimal getComm() {

return comm;

}

public void setComm(BigDecimal comm) {

this.comm = comm;

}

public BigDecimal getDeptno() {

return deptno;

}

public void setDeptno(BigDecimal deptno) {

this.deptno = deptno;

}

public String getEname() {

return ename;

}

public void setEname(String ename) {

this.ename = ename;

}

public String getJob() {

return job;

}

public void setJob(String job) {

this.job = job;

}

}

创建一个 DBHelper 对象用以与数据库进行交互

package com.dao;

import com.tool.UserData;

import java.math.BigDecimal;

import java.sql.*;

import java.util.*;

import java.util.Date;

public class DBHelper {

Connection conn; //数据库连接对象

PreparedStatement pt; //SQL语句预处理对象

ResultSet rs; //结果集对象

public DBHelper(){

try {

Class.forName("oracle.jdbc.driver.OracleDriver"); //装载驱动

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

/**

* 获取当前页的数据

* @param curPage

* @param rowsPerPage

* @return

*/

public List<UserData> getData(int curPage, int rowsPerPage) {

List<UserData> dataList = new ArrayList<>();

String url = "jdbc:oracle:thin:@localhost:1521:orcl";

try {

conn = DriverManager.getConnection(url,"scott","tiger");

String sql = "select * from emp where rownum <= ((? - 1) * "+rowsPerPage+" + "+rowsPerPage+") minus " +

" select * from emp where rownum <= (? - 1) * "+rowsPerPage+" ";

pt = conn.prepareStatement(sql);

pt.setInt(1,curPage);

pt.setInt(2,curPage);

rs = pt.executeQuery();

while (rs.next()){

/**

* 从结果集中取得数据

*/

UserData userData = new UserData();

BigDecimal empno = rs.getBigDecimal("empno");

String ename = rs.getString("ename");

String job = rs.getString("job");

BigDecimal mgr = rs.getBigDecimal("mgr");

Date hireDate = rs.getDate("hiredate");

BigDecimal sal = rs.getBigDecimal("sal");

BigDecimal comm = rs.getBigDecimal("comm");

BigDecimal deptno = rs.getBigDecimal("deptno");

/**

* 设置对象属性

*/

userData.setEmpno(empno);

userData.setEname(ename);

userData.setJob(job);

userData.setMgr(mgr);

userData.setHireDate(hireDate);

userData.setSal(sal);

userData.setComm(comm);

userData.setDeptno(deptno);

dataList.add(userData); //把对象添加集合中

}

rs.close();

pt.close();

conn.close();

} catch (SQLException e) {

e.printStackTrace();

}

return dataList;

}

/**

* 返回总页数

* @return

*/

public int getMaxPage(int rowsPerPage) {

int maxPage;

int maxRowCount = 0;

String url = "jdbc:oracle:thin:@localhost:1521:orcl";

try {

conn = DriverManager.getConnection(url,"scott","tiger"); //创建数据库连接

String sql = "select count(*) from emp";

pt = conn.prepareStatement(sql);

rs = pt.executeQuery();

if (rs.next()){

maxRowCount = rs.getInt(1); //总行数

}

} catch (SQLException e) {

e.printStackTrace();

}

maxPage = (maxRowCount + rowsPerPage - 1) / rowsPerPage; //总页数

return maxPage;

}

}

创建 Servlet 对显示页面进行控制

package com.servlet;

import com.dao.DBHelper;

import com.tool.UserData;

import javax.servlet.RequestDispatcher;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import java.io.IOException;

import java.util.*;

public class Servlet extends HttpServlet {

public int rowsPerPage; //每页显示的行数

public int curPage; //当前页页码

public int maxPage; //总共页数

DBHelper db = new DBHelper();

public Servlet(){

rowsPerPage = 5;

}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

String curPage1 = request.getParameter("page"); //获取当前页页码

if (curPage1 == null){

curPage = 1;

request.setAttribute("curPage",curPage); //设置curPage对象

}else {

curPage = Integer.parseInt(curPage1);

if (curPage < 1){

curPage = 1;

}

request.setAttribute("curPage",curPage);

}

List<UserData> dataList;

dataList = db.getData(curPage,rowsPerPage); //获取当前页的数据

maxPage = db.getMaxPage(rowsPerPage); //获取总页数

request.setAttribute("dataList",dataList);

request.setAttribute("maxPage", maxPage);

RequestDispatcher rd = request.getRequestDispatcher("pagemain.jsp"); //将请求转发到pagemain.jsp页面

rd.forward(request,response);

}

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

doPost(request,response);

}

}

创建 JSP 页面,显示数据。

<%@ page import="java.util.List" %>

<%@ page import="com.tool.UserData" %>

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<html>

<head>

<title>servlet数据分页</title>

<link rel="stylesheet" type="text/css" href="css.css">

</head>

<body>

<div style="margin-top: 15%; margin-left: 25%">

<table>

<caption>SCOTT用户,EMP表中的数据</caption>

<%! int curPage,maxPage; %>

<% curPage =Integer.parseInt(request.getAttribute("curPage").toString()); %> <!--取得当前页-->

<% maxPage =Integer.parseInt((String)request.getAttribute("maxPage").toString()); %> <!--取得总页数-->

<%if (request.getAttribute("dataList") == null){

%>

<tr>

<td colspan="8">没有数据</td>

</tr>

<%

}else {

%>

<tr>

<!--表头-->

<th>EMPNO</th>

<th>ENAME</th>

<th>JOB</th>

<th>MGR</th>

<th>HIREDATE</th>

<th>SAL</th>

<th>COMM</th>

<th>DEPTNO</th>

</tr>

<%

List list = (List) request.getAttribute("dataList");

for (Object aList : list) {

UserData userData = (UserData) aList;

%>

<tr>

<!--取得表中数据-->

<td><%= userData.getEmpno() %></td>

<td><%= userData.getEname() %></td>

<td><%= userData.getJob() %></td>

<td><%= userData.getMgr() %></td>

<td><%= userData.getHireDate() %></td>

<td><%= userData.getSal() %></td>

<td><%= userData.getComm() %></td>

<td><%= userData.getDeptno() %></td>

</tr>

<%

}

}

%>

</table>

</div>

<div style="margin-top: 8%; margin-left: 29%">

第<%= curPage %>页,共<%= maxPage %>页

<%if (curPage > 1){

%>

<a href="Servlet?page=1">首页</a>

<a href="Servlet?page=<%=curPage - 1%>">上一页</a>

<%

}else {

%>

首页 上一页

<%

}%>

<%if (curPage < maxPage){

%>

<a href="Servlet?page=<%=curPage + 1%>">下一页</a>

<a href="Servlet?page=<%=maxPage %>">尾页</a>

<%

}else {

%>

下一页 尾页

<%

}%>

转至第 <form name="form1" action="Servlet" method="get">

<label>

<select name="page" onchange="document.form1.submit()">

<%for ( int i = 1; i <= maxPage; i++){

if (i == curPage){

%>

<!--当前页页码默认选中-->

<option selected value="<%= i%>"><%= i %></option>

<%

}else {

%>

<option value="<%= i %>"><%= i %></option>

<%

}

}%>

</select>

</label>

</form> 页

</div>

</body>

</html>

web.xml

<servlet>

<servlet-name>Servlet</servlet-name>

<servlet-class>com.servlet.Servlet</servlet-class>

</servlet>

<servlet-mapping>

<servlet-name>Servlet</servlet-name>

<url-pattern>/Servlet</url-pattern>

</servlet-mapping>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: