前篇
Servlet的初始化方法
-
Servlet的生命周期:实例化、初始化、服务、销毁
-
Servlet中的初始化方法有两个:init()、init(config)
-
其中带参数的方法代码如下:
public void init(ServletConfig config) throws ServletException { this.config = config ; init(); } -
另外一个无参的init方法如下:
public void init() throws ServletException{ }
如果我们想要在Servlet初始化时做一些准备工作,那么我们可以重写init方法
我们可以通过如下步骤去获取初始化设置的数据:
- 获取config对象:ServletConfig config = getServletConfig();
- 获取初始化参数值: config.getInitParameter(key);
在web.xml文件中配置Servlet
<servlet>
<servlet-name>Demo01Servlet</servlet-name>
<servlet-class>com.atguigu.servlet.Demo01Servlet</servlet-class>
<init-param>
<param-name>hello</param-name>
<param-value>world</param-value>
</init-param>
<init-param>
<param-name>uname</param-name>
<param-value>jim</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Demo01Servlet</servlet-name>
<url-pattern>/demo01</url-pattern>
</servlet-mapping>
也可以通过注解的方式进行配置:
@WebServlet(urlPatterns = {"/demo01"} , initParams = { @WebInitParam(name="hello",value="world"), @WebInitParam(name="uname",value="jim") })
Servlet中的ServletContext和context-param
获取ServletContext,有很多方法:
- 在初始化方法中: ServletContxt servletContext = getServletContext();
- 在服务方法中也可以通过request对象获取,也可以通过session获取: request.getServletContext(); session.getServletContext()
获取初始化值:
- servletContext.getInitParameter();
什么是业务层
-
Model1和Model2
-
MVC : Model(模型)、View(视图)、Controller(控制器)
-
视图层:用于做数据展示以及和用户交互的一个界面
-
控制层:能够接受客户端的请求,具体的业务功能还是需要借助于模型组件来完成
-
模型层:模型分为很多种:有比较简单的pojo/vo(value object),有业务模型组件,有数据访问层组件。
-
pojo/vo : 值对象
-
DAO : 数据访问对象
-
BO : 业务对象
区分业务对象和数据访问对象:
1) DAO中的方法都是单精度方法或者称之为细粒度方法。什么叫单精度?一个方法只考虑一个操作,比如添加,那就是insert操作、查询那就是select操作....
2) BO中的方法属于业务方法,也实际的业务是比较复杂的,因此业务方法的粒度是比较粗的
注册这个功能属于业务功能,也就是说注册这个方法属于业务方法。
那么这个业务方法中包含了多个DAO方法。也就是说注册这个业务功能需要通过多个DAO方法的组合调用,从而完成注册功能的开发。
注册:
1. 检查用户名是否已经被注册 - DAO中的select操作
2. 向用户表新增一条新用户记录 - DAO中的insert操作
3. 向用户积分表新增一条记录(新用户默认初始化积分100分) - DAO中的insert操作
4. 向系统消息表新增一条记录(某某某新用户注册了,需要根据通讯录信息向他的联系人推送消息) - DAO中的insert操作
5. 向系统日志表新增一条记录(某用户在某IP在某年某月某日某时某分某秒某毫秒注册) - DAO中的insert操作
6. ....
在库存系统中添加业务层组件
package com.crystal.service;
import com.crystal.pojo.Fruit;
import java.util.List;
/**
* @author crystal
* @create 2023-02-06 11:55
*/
public interface FruitService {
// 获取所有的信息
List<Fruit> getAll(String keyword,Integer pageNo);
// 添加
void addFruit(Fruit fruit);
// 删除
void delFruit(Integer fid);
// 获取页面的总页数
Integer getCount(String keyword);
// 根据id获取
Fruit getFruitById(Integer fid);
}
package com.crystal.service;
import com.crystal.dao.FruitDAO;
import com.crystal.dao.impl.FruitDAOImpl;
import com.crystal.pojo.Fruit;
import java.util.List;
/**
* @author crystal
* @create 2023-02-06 12:00
*/
public class FruitServiceImpl implements FruitService{
private FruitDAO fruitDAO = new FruitDAOImpl();
@Override
public List<Fruit> getAll(String keyword, Integer pageNo) {
List<Fruit> fruitList = fruitDAO.getAll(keyword, pageNo);
return fruitList;
}
@Override
public void addFruit(Fruit fruit) {
fruitDAO.addFruit(fruit);
}
@Override
public void delFruit(Integer fid) {
fruitDAO.delFruit(fid);
}
@Override
public Integer getCount(String keyword) {
Integer count = fruitDAO.getCount(keyword);
Integer pageCount = (count + 5 - 1) / 5;
return pageCount;
}
@Override
public Fruit getFruitById(Integer fid) {
Fruit fruit = fruitDAO.getFruitByFid(fid);
return fruit;
}
}
package com.crystal.servlet;
import com.crystal.dao.FruitDAO;
import com.crystal.dao.impl.FruitDAOImpl;
import com.crystal.myssm.StringUtil;
import com.crystal.pojo.Fruit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
/**
* @author crystal
* @create 2023-02-04 13:11
*/
public class FruitServlet {
private FruitDAO fruitDAO = new FruitDAOImpl();
private String del(Integer fid) {
if (fid != null){
fruitDAO.delFruit(fid);
return "redirect:fruit";
}
return null;
}
private String add(String fname,Integer price,Integer fcount,String remark) {
fruitDAO.addFruit(new Fruit(null,fname,price,fcount,remark));
return "redirect:fruit";
}
private String index(String oper,String keyword,Integer pageNo,HttpServletRequest request){
HttpSession session = request.getSession();
if (StringUtil.isNotEmpty(oper) && "search".equals(oper)){
// 将页码设置为1,keyword从请求中获取
pageNo = 1;
if (StringUtil.isEmpty(keyword)){
keyword = "";
}
session.setAttribute("keyword",keyword);
}else{
Object keywordObj = session.getAttribute("keyword");
if (keywordObj != null){
keyword = (String) keywordObj;
}else {
keyword = "";
}
}
session.setAttribute("pageNo",pageNo);
FruitDAO fruitDAO = new FruitDAOImpl();
List<Fruit> fruitList = fruitDAO.getAll(keyword,pageNo);
session.setAttribute("fruitList",fruitList);
// 获取所有的条数
Integer count = fruitDAO.getCount(keyword);
Integer pageCount = (count + 5 - 1) / 5;
session.setAttribute("pageCount",pageCount);
// 转发至index.html页面
// super.processTemplate("index",request,response);
return "index";
}
}
IOC
-
耦合/依赖
依赖指的是某某某离不开某某某
在软件系统中,层与层之间是存在依赖的。我们也称之为耦合。
我们系统架构或者是设计的一个原则是: 高内聚低耦合。
层内部的组成应该是高度聚合的,而层与层之间的关系应该是低耦合的,最理想的情况0耦合(就是没有耦合)
IOC - 控制反转 / DI - 依赖注入
public interface BeanFactory {
Object getBean(String id);
}
public class ClassPathXmlApplicationContext implements BeanFactory{
private Map<String,Object> beanMap = new HashMap<>();
public ClassPathXmlApplicationContext(){
try {
// 读取配置文件,将实例装进map集合
InputStream inputStream = getClass().getClassLoader().getResourceAsStream("applicationContext.xml");
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse(inputStream);
NodeList beanNodeList = document.getElementsByTagName("bean");
for (int i = 0; i < beanNodeList.getLength(); i++) {
Node beanNode = beanNodeList.item(i);
if (beanNode.getNodeType() == Node.ELEMENT_NODE){
Element beanElement = (Element) beanNode;
String id = beanElement.getAttribute("id");
String className = beanElement.getAttribute("class");
Class<?> clazz = Class.forName(className);
Object beanClass = clazz.newInstance();
beanMap.put(id,beanClass);
}
}
// 组装bean之间的依赖关系
for (int i = 0; i < beanNodeList.getLength(); i++) {
Node beanNode = beanNodeList.item(i);
if (beanNode.getNodeType() == Node.ELEMENT_NODE) {
Element beanElement = (Element) beanNode;
String id = beanElement.getAttribute("id");
NodeList childNodes = beanElement.getChildNodes();
for (int j = 0; j < childNodes.getLength(); j++) {
Node childNode = childNodes.item(j);
Element child = (Element) childNode;
String childName = child.getAttribute("name");
String childRef = child.getAttribute("ref");
// 根据id获取类
Object beanObj = beanMap.get(id);
Field field = beanObj.getClass().getDeclaredField(childName);
Object refObj = beanMap.get(childRef);
field.setAccessible(true);
field.set(beanObj,refObj);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public Object getBean(String id) {
return beanMap.get(id);
}
}
<?xml version="1.0" encoding="utf-8"?>
<beans>
<bean id="fruitDao" class="com.crystal.dao.impl.FruitDAOImpl"></bean>
<bean id="fruitService" class="com.crystal.service.FruitServiceImpl">
<property name="fruitDao" ref="fruitDao"></property>
</bean>
<bean id = "fruitController" class = "com.crystal.controller.FruitServlet">
<property name="fruitService" ref="fruitService"></property>
</bean>
</beans>
package com.crystal.myssm;
import com.crystal.io.BeanFactory;
import com.crystal.io.ClassPathXmlApplicationContext;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.Map;
/**
* @author crystal
* @create 2023-02-05 15:16
*/
@WebServlet("*.do")
public class DispatcherServlet extends ViewBaseServlet {
private BeanFactory beanFactory;
public DispatcherServlet(){
}
public void init() throws ServletException {
super.init();
beanFactory = new ClassPathXmlApplicationContext();
}
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
// 获取请求的url:http://localhost:8080/pro/hello.do
// 第一步:getServletPath() 获取/hello.do
String servletPath = request.getServletPath();
// 第二步:从/hello.do获取hello.do
servletPath = servletPath.substring(1);
// 获取.do的索引
int lastDotIndexOf = servletPath.lastIndexOf(".do");
servletPath = servletPath.substring(0,lastDotIndexOf);
// 第三步:将获取到的hello ——> HelloController
Object beanObj = beanFactory.getBean(servletPath);
// 获取前端的参数operate
String operate = request.getParameter("operate");
if (operate == null){
operate = "index";
}
// 根据反射调用方法
try {
// 获取方法的参数列表
Method[] methods = beanObj.getClass().getDeclaredMethods();
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
if (operate.equals(method.getName())){
Parameter[] parameters = method.getParameters();
Object[] parameterVals = new Object[parameters.length];
for (int j = 0; j < parameters.length; j++) {
Parameter parameter = parameters[j];
String parameterName = parameter.getName();
if ("request".equals(parameterName)){
parameterVals[j] = "request";
}else if ("response".equals(parameterName)){
parameterVals[j] = "response";
}else if ("session".equals(parameterName)){
parameterVals[j] = request.getSession();
}else{
String parameterval = request.getParameter(parameterName);
parameterVals[j] = parameterval;
Class<?> parameterType = parameter.getType();
Object parameterObj = parameterVals[j];
if (parameterObj != null){
if ("java.lang.Integer".equals(parameterType)){
parameterObj = Integer.parseInt(parameterval);
}
parameterVals[j] = parameterObj;
}
}
}
if (method != null){
// 调用controller中对应的方法
method.setAccessible(true);
Object ObjStr = method.invoke(beanObj,parameterVals);
// 视图处理
String returnStr = (String) ObjStr;
if (returnStr.startsWith("redirect:")){
String redirectVal = returnStr.substring("redirect:".length());
response.sendRedirect(redirectVal);
}else{
super.processTemplate(returnStr,request,response);
}
}else{
throw new RuntimeException("operate的值非法!");
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
package com.crystal.controller;
import com.crystal.dao.FruitDAO;
import com.crystal.dao.impl.FruitDAOImpl;
import com.crystal.myssm.StringUtil;
import com.crystal.pojo.Fruit;
import com.crystal.service.FruitService;
import com.crystal.service.FruitServiceImpl;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.List;
/**
* @author crystal
* @create 2023-02-04 13:11
*/
public class FruitServlet {
private FruitService fruitService = null;
private String del(Integer fid) {
if (fid != null){
fruitService.delFruit(fid);
return "redirect:fruit";
}
return null;
}
private String add(String fname,Integer price,Integer fcount,String remark) {
fruitService.addFruit(new Fruit(null,fname,price,fcount,remark));
return "redirect:fruit";
}
private String index(String oper,String keyword,Integer pageNo,HttpServletRequest request){
HttpSession session = request.getSession();
if (StringUtil.isNotEmpty(oper) && "search".equals(oper)){
// 将页码设置为1,keyword从请求中获取
pageNo = 1;
if (StringUtil.isEmpty(keyword)){
keyword = "";
}
session.setAttribute("keyword",keyword);
}else{
Object keywordObj = session.getAttribute("keyword");
if (keywordObj != null){
keyword = (String) keywordObj;
}else {
keyword = "";
}
}
session.setAttribute("pageNo",pageNo);
List<Fruit> fruitList = fruitService.getAll(keyword,pageNo);
session.setAttribute("fruitList",fruitList);
// 获取所有的条数
Integer pageCount = fruitService.getCount(keyword);
session.setAttribute("pageCount",pageCount);
// 转发至index.html页面
// super.processTemplate("index",request,response);
return "index";
}
}