显示标签为“MVC-C”的博文。显示所有博文
显示标签为“MVC-C”的博文。显示所有博文

问题1:
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.ClassCastException: org.apache.catalina.connector.RequestFacade
程序刚一运行访问就抛出了上面的类型转换异常信息,根据提示信息,找到了导致该异常的代码行:
MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest)request;
MultipartFile file=multipartRequest.getFile("upload");
这个问题花费了我很多时间和精力,查找了很多相关资料之后,发现我的配置文件里少了对multipart解析器的配置:




添加上之后,运行,访问,上面的异常终于没有再出现,但是新的问题又来了

问题2:


org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'multipartResolver' defined in ServletContext resource [/WEB-INF/dispatcher-servlet.xml]: Instantiation of bean failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileItemFactory
这次的问题很明确,缺少文件包,添加commons-fileupload-1.2.jar,问题解决,接着又出新问题

问题3:

org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream
添加commons-io-1.3.1,问题解决,
至此,整个程序终于可以完整的运行,正常上传

又碰到servlet 输出中文乱码的问题,恼火。研究了一下,有了新的发现和认识。

原始代码:

java 代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter pw = response.getWriter();
response.setCharacterEncoding("utf-8");
response.setContentType("text/html; charset=utf-8");
pw.print("中文");
}

无论把3、4两句改成gbk还是utf-8,页面访问到的一律是??

一怒之下用wpe抓包,发现无论设为utf-8还是gbk抓到的均为

HTTP 代码
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 2
Date: Thu, 08 Mar 2007 06:04:55 GMT

??

说明3、4两句没起作用,检查代码,尝试把2和三四顺序调整,乱码问题解决。

检查api文档,发现说明如下

PrintWriter getWriter() throws IOException

Returns a PrintWriter object that can send character text to the client. The PrintWriter uses the character encoding returned by getCharacterEncoding(). If the response's character encoding has not been specified as described in getCharacterEncoding (i.e., the method just returns the default value ISO-8859-1), getWriter updates it to ISO-8859-1.

推断getWriter()返回的PrintWriter使用的charactor encoding是在这个函数返回时即已确定的,但到底是返回的PrintWriter内部属性还是运行时的控制,未找到依据。

查看 tomcat中setCharacterEncoding方法的实现时发现如下代码:

java 代码
public void setCharacterEncoding(String charset) {

if (isCommitted())
return;

// Ignore any call from an included servlet
if (included)
return;

// Ignore any call made after the getWriter has been invoked
// The default should be used
if (usingWriter)
return;

coyoteResponse.setCharacterEncoding(charset);
isCharacterEncodingSet = true;
}

其中usingWriter 标志为getPrinteWriter方法中设定,可见其控制逻辑为一旦返回了PrintWriter,本函数即不再生效。但是上述的推断没有进一步的证据。

同时我们发现只有usingWriter标志,却没有usingOutputStream标记。猜测使用ServletOutputStream 输出不受此限制,经测试写出如下代码。

java 代码
ServletOutputStream out = response.getOutputStream();
out.print("中文");

//情况1:正常,浏览器按utf-8方式查看
//response.setContentType("text/html; charset=utf-8");

//情况2:浏览器缺省按简体中文查看,手动设为utf-8方式查看正常
//response.setCharacterEncoding("utf-8");

说明:这种方式不仅不需要在调用getOutputStream()之前设定字符集,甚至在print输出后设定都有效。


查看setCharacterEncoding API文档,进一步发现:

Calling setContentType(java.lang.String) with the String of text/html and calling this method with the String of UTF-8 is equivalent with calling setContentType with the String of text/html; charset=UTF-8.

原来只需要用response.setContentType("text/html; charset=utf-8"); 设定就ok,不需要两次调用。进一步

This method can be called repeatedly to change the character encoding. ......If the character encoding has already been set by setContentType(java.lang.String) or setLocale(java.util.Locale), this method overrides it.

可反复设置,相互覆盖,据此写出如下测试代码

java 代码


//情况1:正常,浏览器按utf-8方式查看
response.setContentType("text/html; charset=gbk");
response.setCharacterEncoding("utf-8");
//情况2:正常,浏览器按简体中文方式查看
//response.setContentType("text/html; charset=utf-8");
//response.setCharacterEncoding("gbk");

PrintWriter pw = response.getWriter();
pw.print("中文");

结论:

1.在servlet中输出中文,如果采用PrintWriter方式,需要在调用getPrintWriter()之前调用setContentType 或者 setCharacterEncoding;采用ServletOutputStream方式,不受此限。

2.setContentType 和 setCharacterEncoding两方法中设定characterEncoding的方法对服务器效果一致,不需要反复调用。在输出文本内容时,采用response.setContentType("text/html; charset=utf-8");似乎更为方便。

detail:

http://community.csdn.net/Expert/TopicView3.asp?id=5675034

ajax 传输表单

function preceping(){
var url = "<%=request.getContextPath()%>/quxian/preCeping.shtml?tp=changyetouzi";
var form = Form.serialize('frmId');
var myAjax = new Ajax.Updater('zongfen',url, {method: 'get', parameters: form});
}


注意prototype的版本

读取factorybean

ClassPathResource s=new ClassPathResource("beans.xml")
XmlBeanFactory x=new XmlBeanFactory(s);
//根路径指定->class文件夹开始找beans.xml

ClassPathXmlApplicationContext cx=new ClassPathXmlApplicationContext("beans.xml");
//根路径指定->class文件夹开始找beans.xml

ApplicationContext c=new FileSystemXmlApplicationContext("beans.xml");
//根路径指定->项目根路径 开始找beans.xml

AfterReturningAdvice

public interface AfterReturningAdvice extends Advice {
void afterReturning(Object returnValue, Method m,Object[] args, Object target) throws Throwable;
}


AfterReturningAdvice直接继承自Advice介面,afterReturning()当中传入的引数有目标方法的返回值、方法实例、引数、与目标物件,afterReturning()方法传回void,若您要中止接下来的应用程式流程,丢出例外是唯一的方式。

// 特殊字符转为Html
public static String toHtml(String s){
if(s == null){
s = "";
return s;
}
s = Replace(s.trim(),"&","&amp;");
s= Replace(s.trim(),"<","<");
s = Replace(s.trim(),">",">");
s = Replace(s.trim(),"\t"," ");
s = Replace(s.trim(),"\r\n","\n");
s = Replace(s.trim(),"\n","
");
s = Replace(s.trim()," "," ");
s = Replace(s.trim(),"'","'");
s = Replace(s.trim(),"\\","\");
return s;
}
/**
* ubb
*/
public static String toUbbHtml(String s){
if(s == null){
s = "";
return s;
}
s = Replace(s,"\n","
");
s = Replace(s," "," ");
s = Replace(s,"'","'");
s = Replace(s,"\\","\");
return s;
}

//逆
public static String unHtml(String s){
s = Replace(s,"
","\n");
s = Replace(s," "," ");
return s;
}

public static String Replace(String source,String oldString,String newString){
StringBuffer output = new StringBuffer();
int lengthOfsource = source.length();//源字符串长度
int lengthOfold = oldString.length();//老字符串长度
int posStart = 0;//开始搜索位置
int pos;//搜索到的老字符串的位置
//source.indexOf(oldString,posStart)检索某子串在字符串postStart以后第一次出现的位置,如果未找到就返回一个-1。
while((pos = source.indexOf(oldString,posStart)) >= 0){//得到字符串的位置(eg:如果有
就执行,没有就跳出,不要处理。)
//将以posStart起始以pos-1结束之间的内容拷贝到另一个字符串中。因为posStar从0开始的。
output.append(source.substring(posStart,pos));//append方法将文本添加到当前StringBuffer对象内容的结尾。
output.append(newString);//替换成新字符串
posStart = pos + lengthOfold;//位置也变为找到了之后的位置,pos为得到第一次出现字符的位置,lengthold为字符的长度
}
if(posStart < lengthOfsource){
//source.substring(posStart)以lengthOfsource开始的字符串拷贝到列一个字符串中
output.append(source.substring(posStart));
}
//这个方法将其内容转换成一个可以被用于输出的字符串对象。它允许操作对应的文本用于输出或数据存储。
return output.toString();
}

一个是标准输出 一个是标准错误输出 在不同的容器,System.out.println() 和System.err.println()会输出 不同的文件中。

System.err.println()不能被重定向


System.out.println() 是标准输出 System.err.println() 是标准错误输出 默认情况下都是将结果输出到控制台,不过可以对其进行重定向从而改变其默认输出的方式。

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Random;
import java.util.Set;

public class Test {
public static void main(String[] args){
ArrayList arr = new Test().getRandom(10);
Iterator it = arr.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
}
public ArrayList getRandom(int num){
ArrayList randomNum = new ArrayList();
Random random = new Random();
int temp = 0;
for (int i = 0;i < num; i ++){
temp = random.nextInt(num);
int nums = temp + 1;
if (randomNum.indexOf(new Integer(nums)) == -1){
randomNum.add(new Integer(nums));
}else{
i -- ;
}
}
return randomNum;
}
}

 
Copyright 2005-2007. Hello Wiki designed by Fen, Blogger Templates by Blogcrowds.