[code="java"]Map root = new HashMap();
root.put("message", "Hello World!");
Template t = cfg.getTemplate("test.ftl");
System.out.println(t.getEncoding());//GBK编码
response.setContentType("text/html; charset=" + t.getEncoding());
Writer out = response.getWriter();
try {
t.process(root, out);
} catch (TemplateException e) {
throw new ServletException(
"Error while processing FreeMarker template", e);
} [/code]
这是http get或者post方法里面的内容.主要问题是try...catch..部分的问题.里面执行的是Template中的process方法.
执行这个方法可能会抛出异常.
问题:
抛出异常时无法设置response的状态码.返回的居然还是200状态码.而我请求端是根据状态码来处理的.出异常了还200的话.我会请求端会得到异常信息直接返回给用户.这样是不行的.请问下,抛出异常时改如何设置response的错误状态码呢??
执行t.process(root,out)前设置是有效的.执行后设置是无效的..知道的朋友们帮忙回答下~~ 因为没分了.所以没办法给分.只能表示万分感谢了~~~
[code="java"]
CharArrayWriter out = new CharArrayWriter(1000);
//...
resp.getWriter().write(out.toCharArray());
resp.flushBuffer();
[/code]
这样不就可以把它写入到响应了吗!
你是不是在 process 中对 out 进行了什么操作啊?把对 out 的操作贴出来吧。
另外,你先试试下面的方法呢,在 catch 里面加上:
[code="java"]
response.reset();
response.setXXXX(); // 设置response状态码
[/code]
1,你把异常打出来,先不要重新抛出
2,在process后面加上
out.flush();
out.close();试试。
你异常先不要抛出,打出来,把你异常贴出来吧
那么估计是你ftl文件里面的属性没有对应。
[quote]恩.是这样的.我没有ftl文件.直接在内存中弄的.这个异常是我故意弄出来的.因为我在测试的时候.得到了这边的异常信息.异常信息不应该返回给用户.但是出异常的时候.response无法设置错误码.还是200.所以才看看出现异常时要怎么样才能重新设置response的错误码 [/quote]
两个比较常用的方法是setStatus和sendError
[quote]恩 这两个都试过了.只要在执行process方法之后.就没办法设置了.执行之前还是设置的有效.执行之后设置就无效了~~ 难道还要去看process源码.再修改源码..泪奔了.. [/quote]
别急啊,我觉得执行之后,已经修改了response并且刷新了,所以你执行之后再加上
out.flush();
out.close();试试。
恩,你试试再说吧。
我估计在process里面response就已经被刷新了。
因为报java.lang.IllegalStateException这个异常就说明sendError调用了多次。
[quote]
抛出异常时无法设置response的状态码.返回的居然还是200状态码.而我请求端是根据状态码来处理的.出异常了还200的话.我会请求端会得到异常信息直接返回给用户.这样是不行的.请问下,抛出异常时改如何设置response的错误状态码呢??
[/quote]
这个问题的关键在于“process”执行后,响应已经提交了(你可以在这个方法前后调用response.isCommitted()来查看响应是否提交),所以后面你再更改什么状态都是无效的,至于reset,更会抛出非法状态异常。
你可以看看[code="java"]t.process(root, out); [/code]的实现,内部调用了[code="java"]out.flush();[/code]。所以,你这条路应该走不通。你可以先把模板的输出放到一个CharArrayWriter,有你自己决定是否把它写入到response.getWriter(),这样在你设置好响应状态后,自己提交响应,应该不会有问题。
要不你继承Template这个类,然后重写process方法。
[quote]reset():清除缓冲区中存在的所有数据以及状态代码和头。如果已提交响应,则此方法将抛出 IllegalStateException。[/quote]
所以,兄弟,你在process() 后调用 isCommitted() 方法来判断response 是否已经提交过,如果已经提交过,那么,你只能进 process() 方法里去一探究竟了。
如果你要重写 process() 方法,要记得一定不能影响到其他使用process()方法的代码。真是动一发而牵全身啊。
[quote]恩 我再想想办法 如果不行。只能这么做了.谢谢啦~ [/quote]
继承的东西你可以用也可以不用,需要的时候就用你的子类,不需要就用原类,不会影响所有的。