Servlet:
servlet的基本作用
第一个servlet程序:
//演示servlet的生命周期
public class Demo02Servlet extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("正在初始化。。。");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("正在服务。。。");
}
@Override
public void destroy() {
System.out.println("正在销毁。。。");
}
}
当编写一个servlet类去继承HttpServlet时,主要是重写service方法。service中包含doPost(),doGet()等方法,可以不重写service(),直接按照请求的类型重写doPost(),doGet()等
public class Demo01Servlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
session:会话
HTTP无状态︰服务器无法判断这两次请求是同一个客户端发过来的,还是不同的客户端发过来的
因此通过会话跟踪技术来解决无状态的问题
public class Demo03Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//获取session.如果获取不到,则创建一个新的
HttpSession session = req.getSession();
System.out.println("session ID"+session.getId());
}
}
内部转发 与重定向 (URL都会变化)
内部转发:一次请求,一次响应 重定向:两次请求,两次响应
//演示服务器端内部转发以及客户端重定向
public class Demo04Servlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("demo04。。。。");
//服务器端内部转发
//req.getRequestDispatcher("demo07").forward(req,resp);//这里的s指的就是要跳转的组件
resp.sendRedirect("demo05");
}
}
thymeleaf:
编写ViewBaseServlet类,其他servlet类基础由原先的HttpServlet改成ViewBaseServlet
public class ViewBaseServlet extends HttpServlet {
private TemplateEngine templateEngine;
@Override
public void init() throws ServletException {
// 1.获取ServletContext对象
ServletContext servletContext = this.getServletContext();
// 2.创建Thymeleaf解析器对象
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(servletContext);
// 3.给解析器对象设置参数
// ①HTML是默认模式,明确设置是为了代码更容易理解
templateResolver.setTemplateMode(TemplateMode.HTML);
// ②设置前缀
String viewPrefix = servletContext.getInitParameter("view-prefix");
templateResolver.setPrefix(viewPrefix);
// ③设置后缀
String viewSuffix = servletContext.getInitParameter("view-suffix");
templateResolver.setSuffix(viewSuffix);
// ④设置缓存过期时间(毫秒)
templateResolver.setCacheTTLMs(60000L);
// ⑤设置是否缓存
templateResolver.setCacheable(true);
// ⑥设置服务器端编码方式
templateResolver.setCharacterEncoding("utf-8");
// 4.创建模板引擎对象
templateEngine = new TemplateEngine();
// 5.给模板引擎对象设置模板解析器
templateEngine.setTemplateResolver(templateResolver);
}
protected void processTemplate(String templateName, HttpServletRequest req, HttpServletResponse resp) throws IOException {
// 1.设置响应体内容类型和字符集
resp.setContentType("text/html;charset=UTF-8");
// 2.创建WebContext对象
WebContext webContext = new WebContext(req, resp, getServletContext());
// 3.处理模板数据
templateEngine.process(templateName, webContext, resp.getWriter());
}
在Web.xml中配置上下文参数(ViewBaseServlet中的前缀和后缀)
<!--配置上下文参数-->
<context-param>
<param-name>view-prefix</param-name>
<param-value>/</param-value>
</context-param>
<context-param>
<param-name>view-suffix</param-name>
<param-value>.html</param-value>
</context-param>
编写一个普通的Post请求的Servlet:
@WebServlet("/add.do")
public class AddServlet extends ViewBaseServlet {
private FruitDAO fruitDAO = new FruitDAOImpl();
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String fname = req.getParameter("fname");
String fcountStr = req.getParameter("fcount");
String priceStr = req.getParameter("price");
String remark = req.getParameter("remark");
int fcount = Integer.parseInt(fcountStr);
int price = Integer.parseInt(priceStr);
fruitDAO.addFruit(new Fruit(0,fname,fcount,price,remark));
resp.sendRedirect("index");
}
}
编写一个普通的Get请求:
@WebServlet("/index")
public class IndexServlet extends ViewBaseServlet {
private FruitDAO fruitDAO = new FruitDAOImpl();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
Integer pageNo = 1;
HttpSession session = req.getSession();
String oper = req.getParameter("oper");
//如果oper!=null 说明 通过表单的查询按钮点击过来的
//如果oper是空的,说明 不是通过表单的查询按钮点击过来的
String keyword = null;
if (StringUtil.isNotEmpty(oper)&&"search".equals(oper)){
//说明是点击表单查询发送过来的请求
//此时,pageNo应该还原为1,keyword应该从请求参数中获取
pageNo=1;
keyword = req.getParameter("keyword");
if(StringUtil.isEmpty(keyword)){
keyword="";
}
session.setAttribute("keyword",keyword);
}
else {
//说明此处不是点击表单查询发送过来的请求(比如点击上下页或者直接从地址栏输入网址) 此时keyword应该从session作用域获取 (可能先输入关键字查询,再做翻页操作)
String pageNoStr= req.getParameter("pageNo");
if (StringUtil.isNotEmpty(pageNoStr)){
pageNo = Integer.parseInt(pageNoStr);
}
Object keywordObj = session.getAttribute("keyword");
if(keywordObj!=null){
keyword = (String) keywordObj;
}else {
keyword="";
}
}
// List<Fruit> fruitList = fruitDAO.getFruitList();
//保存到session作用域
session.setAttribute("pageNo",pageNo);
int fruitCount = fruitDAO.getFruitCountByKey(keyword);
int pageCount = (fruitCount+5-1)/5;
session.setAttribute("pageCount",pageCount);
List<Fruit> fruitList = fruitDAO.getFruitListPageByKey(keyword,pageNo);
session.setAttribute("fruitList",fruitList);
//此处视图名称是index
//那么thymeleaf会将这个 逻辑视图名称 对应到 物理视图 名称上去
//逻辑视图名称: index
//物理视图名称: view_prefix + 逻辑视图名称 + view-suffix (web.xml自己配置的)
//所以真实的视图名称是: / index .html
super.processTemplate("index",req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}