和Dao层类似,Service层也需要有Service接口和其实现类,这一层主要是处理Dao层的异常问题,以及对数据的再封装,如果说Dao层方法获取的数据是我们点外卖购买的披萨,那么Service层的方法就好比是将披萨用精美的包装盒给包装起来,包装盒里为了让食物不那么快冷掉,店员还会用锡纸再包裹一层,那么客人拿到的就不是一个裸在外面的披萨了,用户的体验度也会更好,试想一下,如果你收到的是一个没有包装盒的披萨,或者说用手提袋装着,看起来会很难受没有食欲对吧,哈哈哈~
这里扯远了,我们回归正题
Service接口
public interface UserService {
Result listUsers(Map<String, Object> map);
Result editUser(Map<String, Object> map);
Result addUser(Map<String, Object> params);
Result delUser(List<Integer> ids);
User listUserById(int id);
}
public interface CustomerService {
Result listCustomers(Map<String, Object> map);
Result editCustomer(Map<String, Object> map);
Result addCustomer(Map<String, Object> params);
Result delCustomer(List<Integer> ids);
Customer listCustomerById(int id);
}
public interface ContractService {
Result listContracts(Map<String, Object> map);
Result addContract(Map<String, Object> params);
Result delContract(List<Integer> ids);
}
以上就是我们的Service层接口,说句题外话,有的时候我真的觉得取名字是一件特别麻烦的事情,特别是像Service跟Dao,如果数据处理比较简单,方法用途一个样,索性我就取一样的名字啦,哈哈哈,你们可以自行发挥。
ServiceImpl实现类
public class UserServiceImpl implements UserService {
UserDao userDao = new UserDaoImpl();
@Override
public Result listUsers(Map<String, Object> map) {
PageQueryInfo pageInfo = userDao.listUsers(map);
Result result = new Result(CodeMsg.SUCCESS, pageInfo);
return result;
}
@Override
public Result addUser(Map<String, Object> params) {
Result result = new Result(CodeMsg.ADD_DATA_FAILED);
User user = mapToUser(params);
try {
boolean flag = userDao.addUser(user);
if(flag) {
result = new Result(CodeMsg.SUCCESS);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
private User mapToUser(Map<String, Object> params) {
String id = params.get("id") == null? "0":(params.get("id") + "");
String userName = params.get("userName") + "";
String password = params.get("password") + "";
String realName = params.get("realName") + "";
User user = new User(Integer.parseInt(id), userName, password, realName);
return user;
}
@Override
public Result delUser(List<Integer> ids) {
Result result = new Result(CodeMsg.DELETE_DATA_FAILED);
boolean flag;
flag = userDao.delUser(ids);
result = new Result(CodeMsg.SUCCESS);
if(flag) {}
return result;
}
@Override
public Result editUser(Map<String, Object> params) {
Result result = new Result(CodeMsg.EDIT_DATA_ERROR);
try {
boolean flag = userDao.editUser(mapToUser(params));
if(flag) {
result = new Result(CodeMsg.SUCCESS);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
@Override
public User listUserById(int id) {
User user = userDao.queryById(id);
return user;
}
}
老样子,Customer的方法和User也差不多,我这里就略啦
public class ContractServiceImpl implements ContractService {
ContractDao contratDao = new ContractDaoImpl();
@Override
public Result listContracts(Map<String, Object> params) {
PageQueryInfo pageInfo = contratDao.listContracts(params);
Result result = new Result(CodeMsg.SUCCESS, pageInfo);
return result;
}
@Override
public Result addContract(Map<String, Object> params) {
Result result = new Result(CodeMsg.ADD_DATA_FAILED);
Contract contract = mapToContract(params);
try {
boolean flag = contratDao.addContract(contract);
if(flag) {
result = new Result(CodeMsg.SUCCESS);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
private Contract mapToContract(Map<String, Object> params) {
String id = params.get("id") == null? "0":(params.get("id") + "");
String saleId = params.get("saleId") == null? "0":(params.get("id") + "");
String custId = params.get("custId") == null? "0":(params.get("id") + "");
String createTime = params.get("endDate") == null? null: (params.get("endDate") + "");
String content = params.get("content") == null? "": (params.get("remark") + "");;
Contract contract = new Contract(Integer.parseInt(id), Integer.parseInt(saleId), Integer.parseInt(custId), content, createTime);
return contract;
}
@Override
public Result delContract(List<Integer> ids) {
Result result = new Result(CodeMsg.DELETE_DATA_FAILED);
boolean flag;
try {
flag = contratDao.delContract(ids);
if(flag) {
result = new Result(CodeMsg.SUCCESS);
}
} catch (SQLException e) {
e.printStackTrace();
}
return result;
}
}
终于到Servlet层了,也就离胜利不远了… 坚持一下,Servlet隶属于MVC模型中的Controller,我个人觉得他的意义和Dao层差不多,一个是建立Java程序和数据库的联系,一个是建立Java程序和页面的联系,两者都扮演着桥梁的角色,缺一不可。
一般来说我们需要建立xml文件来完成URL请求地址和Servlet之间的映射关系,但是Servlet 3.0之后,就添加了使用注解配置映射关系,这就是我一直没有提到xml配置的原因,省事儿!
注意了我们Servlet的urlPatterns习惯性在后面加上".do",当然不是说没有用处,在后面加上".do"可以在后期我们做过滤器拦截的时候用到,试想如果没有做拦截,那跟光着身子出去有什么分别!
@WebServlet(urlPatterns = "/user.do")
public class UserServlet extends HttpServlet{
private static final long serialVersionUID = 5071054518116423034L;
UserService userSvc = new UserServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String method = request.getParameter("method");
if("addUser".equals(method)) {
this.addUser(request,response);
}else if("delUser".equals(method)) {
this.delUser(request,response);
} else if("editUser".equals(method)) {
this.editUser(request,response);
} else if("userList".equals(method)) {
this.userList(request,response);
} else if("toEditUser".equals(method)) {
this.toEditUser(request, response);
}
}
private void userList(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> params = ServletUtil.putInMap(request, "userName","realName","page","limit");
Result result = userSvc.listUsers(params);
ServletUtil.print(result, response);
}
private void toEditUser(HttpServletRequest request, HttpServletResponse response) {
if(!CheckParamUtil.isBlank(request.getParameter("id"))) {
int id = Integer.parseInt(request.getParameter("id"));
User user = userSvc.listUserById(id);
request.setAttribute("user", user);
try {
request.getRequestDispatcher("view/user/editUser.jsp").forward(request, response);
} catch (ServletException | IOException e) {
e.printStackTrace();
}
}
}
private void editUser(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> params = ServletUtil.putInMap(request, "id", "userName","password","realName");
Result result = userSvc.editUser(params);
ServletUtil.print(result, response);
}
private void delUser(HttpServletRequest request, HttpServletResponse response) {
String idsStr = request.getParameter("ids");
if(!CheckParamUtil.isBlank(idsStr)) {
Result result = userSvc.delUser(JSONArray.parseArray(idsStr, Integer.class));
ServletUtil.print(result, response);
}
}
private void addUser(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> params = ServletUtil.putInMap(request, "userName","password","realName");
Result result = userSvc.addUser(params);
ServletUtil.print(result, response);
}
}
@WebServlet(urlPatterns = "/customer.do")
public class CustomerServlet extends HttpServlet{
private static final long serialVersionUID = 5071054518116423034L;
CustomerService customerSvc = new CustomerServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String method = request.getParameter("method");
if("addCust".equals(method)) {
this.addCust(request,response);
}else if("delCust".equals(method)) {
this.delCust(request,response);
} else if("editCust".equals(method)) {
this.editCust(request,response);
} else if("custList".equals(method)) {
this.custList(request,response);
} else if("toEditCust".equals(method)) {
this.toEditCust(request,response);
}
}
private void toEditCust(HttpServletRequest request, HttpServletResponse response) {
if(!CheckParamUtil.isBlank(request.getParameter("id"))) {
int id = Integer.parseInt(request.getParameter("id"));
Customer customer = customerSvc.listCustomerById(id);
request.setAttribute("customer", customer);
try {
request.getRequestDispatcher("view/customer/editCust.jsp").forward(request, response);
} catch (ServletException | IOException e) {
e.printStackTrace();
}
}
}
private void custList(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> params = ServletUtil.putInMap(request, "custName","custComp","page","limit");
Result result = customerSvc.listCustomers(params);
ServletUtil.print(result, response);
}
private void editCust(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> params = ServletUtil.putInMap(request, "id", "custName","custComp");
Result result = customerSvc.editCustomer(params);
ServletUtil.print(result, response);
}
private void delCust(HttpServletRequest request, HttpServletResponse response) {
String idsStr = request.getParameter("ids");
if(!CheckParamUtil.isBlank(idsStr)) {
Result result = customerSvc.delCustomer(JSONArray.parseArray(idsStr, Integer.class));
ServletUtil.print(result, response);
}
}
private void addCust(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> params = ServletUtil.putInMap(request, "custName","custComp");
Result result = customerSvc.addCustomer(params);
ServletUtil.print(result, response);
}
}
好了,Servelt就到这了,Contract那个也类似,这个大家自己可以完成吧,哈哈哈。
接下来细节部分到了,所谓细节决定成败,那么我们第一个关于Servlet的小细节就是关于编码的问题。
细节一:
这个相信一直都是一个困扰初学者的问题,我也不例外。。编码问题不解决编程就玩不下去了,毕竟代码写好了,结果显示乱码?Are You Kidding Me?
那么来了,万能处理乱码问题的方案!
低调,牛逼吹大了,数据库你老老实实给我用utf-8吧。
@WebFilter(urlPatterns = "/*")
public class EncodingFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRqst = (HttpServletRequest)request;
HttpServletResponse httpResp = (HttpServletResponse)response;
httpRqst.setCharacterEncoding("UTF-8");
httpResp.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
}
Filter属于Servlet中不可或缺的部分之一,用好Filter可以减少我们的很多麻烦,不仅仅是处理编码问题,还可以处理拦截问题,还可以处理Session失效后ajax请求异常问题等等。
细节二:
除了Filter接口,Servelt中还有一个接口很重要,也就是Listener接口(监听者)
不知道大家对这个接口第一想法是什么,反正第一次接触的时候听到这个名词就感觉很吊。。窃听风云?
好。。打住,监听顾名思义,就是监听我们的程序,有什么用呢?
使用监听,我就可以知道你是上线了,还是下线了,我还可以统计我们这个页面或者我们网站的访问量,月度,季度,年度访问量,我可以在应用启动的时候初始化配置,我可以在初始化一些数据,使得我们第一次启动应用时不会出现空指针,我还可以知道你的账户被是不是同时登录了多个,如果是,我可以把你另一个踢下去。。等等。
那么这里我们主要用到的是初始化配置,提到配置,这里我自己建了一个urlConfig.properties文件,然后新建监听类UrlConfigListener实现ServletContextListener接口,相信了解过域对象大家应该知道ServletContext的作用范围吧。不懂的小伙伴可以戳 Marco’s Java 之【Servlet基础】
webUrlHeader=http://127.0.0.1:8080/crs/
@WebListener
public class UrlConfigListener implements ServletContextListener {
/**
* @see ServletContextListener#contextDestroyed(ServletContextEvent)
*/
public void contextDestroyed(ServletContextEvent sce) {
}
/**
* @see ServletContextListener#contextInitialized(ServletContextEvent)
*/
public void contextInitialized(ServletContextEvent sce) {
Properties prop = new Properties();
ServletContext context = sce.getServletContext();
try {
prop.load(UrlConfigListener.class.getClassLoader().getResourceAsStream("urlConfig.properties"));
String webUrlHeader = prop.getProperty("webUrlHeader");
context.setAttribute("webUrlHeader", webUrlHeader);
} catch (IOException e) {
e.printStackTrace();
}
}
}
大家可能会疑惑webUrlHeader干啥用的啊?
用处大了,我们在jsp界面上不是会导一些文件么,比如说我导入的layui框架中的css样式和js,我们的页面不都放在view文件夹中么,那么大家有没有想过一个问题,我在view中的文件如果要导文件,我这么写可不可以
<script type="text/javascript" src="layui/layui.js">script>
这样显然是导不进来的,因为我们的文件是置于WebRoot根目录下,但是view里面又套了几个子文件夹,所以我们要导入的文件路径是相对与根目录的,那么导文件的路径应该这么写
<script type="text/javascript" src="../../layui/layui.js">script>
那么大家现在应该猜到为什么我们要获取配置webUrlHeader并放置到ServletContext作用域了吧
<script type="text/javascript" src="${webUrlHeader}layui/layui.js">script>
可以这样大家觉得还是不够,我用"…/…/“能解决的问题,为什么还要用${webUrlHeader} EL表达式获取它啊,不麻烦吗?起初我也这么想,但是大家想一下,有可能我们的文件可能在view文件夹的子文件夹的子文件夹中,那么我不得写”…/…/…/"啊,如果说还是觉得麻烦,那。。。我们讲下一个
细节三
有朋友可能说,欸,照你的代码我复制粘贴了一遍,包也导入了,上面提到的文件也有,怎么运行不起来啊?
这就是我把这一点放在这里讲的原因,因为初学者很容易忽略的两点,一是导入JDBC驱动jar包mysql-connector-java-5.1.47.jar
,还有一个就是我的驱动是靠properties文件导入的。。
所以还漏了一个配置文件config.properties,注意了这些properties文件都是放在Java的src路径下,并且使用ClassLoader.getResourceAsStream()的方式读取,否则可能读取不到
driver=com.mysql.jdbc.Driver
password=zcq774798947
url=jdbc:mysql://127.0.0.1:3306/crs?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username=root