day21 思维导图
1、案例三:解决全站字符乱码(POST和GET中文编码问题)
1.问题说明:
获取请求参数式发生的乱码问题;
POST请求:request.setCharacterEncoding(“utf-8”);
GET请求:new String(request.getParameter(“xxx”).getBytes(“iso-8859-1”), “utf-8”);
响应的乱码问题:response.setContextType(“text/html;charset=utf-8”)。
基本上在每个Servlet中都要处理乱码问题,所以应该把这个工作放到过滤器中来完成。
2.难点:处理GET请求参数的问题。
原因:request只有getParameter(),而没有setParameter()方法。不能将编码后的字符放入request。
解决:掉包request。
1)在新的request中在servlet中重写getParameter()方法,直接完成编码处理。 (装饰者模式)
2)返回新的request,在servlet中调用即可。
而post请求中含有request.setCharacterEncoding()方法可直接设置
掉包原理:使用装饰者模式
servlet
public class AServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
response.getWriter().println(username);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=utf-8");
String username = request.getParameter("username");
response.getWriter().println(username);
}
}
Filter
public class AFilter implements Filter {
public void destroy() {}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
HttpServletRequest req = (HttpServletRequest) request;
if(req.getMethod().equals("GET")) {
EncodingRequest er = new EncodingRequest(req);
chain.doFilter(er, response);
} else if(req.getMethod().equals("POST")) {
chain.doFilter(request, response);
}
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
/**
* 装饰request
* @author 一万年行不行
*/
public class EncodingRequest extends HttpServletRequestWrapper {
private HttpServletRequest req;
public EncodingRequest(HttpServletRequest request) {
super(request);
this.req = request;
}
public String getParameter(String name) {
String value = req.getParameter(name);
try {
value = new String(value.getBytes("iso-8859-1"), "utf-8");
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
return value;
}
}
2、案例四:页面静态化
1)什么是页面静态化:
首次访问去数据库获取数据,然后把数据保存到一个html页面中
二次访问,就不再去数据库获取了,而是直接显示html
2)原理:
1.使用过滤器,把servlet请求的资源所做的输出保存到本地指定路径中,然后将请求重定向到html页面。
2.二次访问时,这个html已经存在,那么直接重定向,不用再去访问servlet!
适用情景:很少发生变化的页面
步骤:
1)搭建背景环境(图书管理项目)
写一个小项目,图书管理
1.需要创建数据库
2.导包
3.页面:
* jsp:link.jsp
链接页面,四个超链接:
> 查询所有
> 查看SE分类
> 查看EE分类
> 查看框架分类
* show.jsp
显示查询结果
4.Servlet(继承BaseServlet):
BookServlet
* findAll() --> 查看所有图书
* findByCategory --> 按分类进行查询
5.BookService;略
6.BookDao;
* List<Book> findAll()
* List<Book> findByCategory(int category)
7.domain:Book类
Book:略
BookDao
public class BookDao {
private QueryRunner qr = new TxQueryRunner();
public List<Book> findAll() {
try {
String sql = "select * from t_book";
return qr.query(sql, new BeanListHandler<Book>(Book.class));
} catch(SQLException e) {
throw new RuntimeException(e);
}
}
public List<Book> findByCategory(int category) {
try {
String sql = "select * from t_book where category=?";
return qr.query(sql, new BeanListHandler<Book>(Book.class), category);
} catch(SQLException e) {
throw new RuntimeException(e);
}
}
}
Servlet
public class BookServlet extends BaseServlet {
private BookDao bookDao = new BookDao();
public String findAll(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setAttribute("bookList", bookDao.findAll());
return "f:/show.jsp";
}
public String findByCategory(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String value = request.getParameter("category");
int category = Integer.parseInt(value);
request.setAttribute("bookList", bookDao.findByCategory(category));
return "f:/show.jsp";
}
}
Filter
public class StaticFilter implements Filter {
private FilterConfig config;
public void destroy() {}
public void init(FilterConfig fConfig) throws ServletException {
this.config = fConfig;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String category = request.getParameter("category");
String htmlPage = category + ".html";
String htmlPath = config.getServletContext().getRealPath("/htmls");
File destFile = new File(htmlPath, htmlPage);
if(destFile.exists()) {
res.sendRedirect(req.getContextPath() + "/htmls/" + htmlPage);
return;
}
StaticResponse sr = new StaticResponse(res, destFile.getAbsolutePath());
chain.doFilter(request, sr);
res.sendRedirect(req.getContextPath() + "/htmls/" + htmlPage);
}
}
/**
* 掉包response
* @author 一万年行不行
*
*/
public class StaticResponse extends HttpServletResponseWrapper {
private PrintWriter pw;
/**
* String path:html文件路径!
*
* @param response
* @param path
* @throws UnsupportedEncodingException
* @throws FileNotFoundException
*/
public StaticResponse(HttpServletResponse response, String path)
throws FileNotFoundException, UnsupportedEncodingException {
super(response);
pw = new PrintWriter(path, "utf-8");
}
public PrintWriter getWriter() {
return pw;
}
}
问题:通过show.jsp生成的html文件会中文乱码
原因:文件头中未声明编码类型
解决: 在show.jsp页面文件头中添加语句声明
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">