The whole project has been uploaded to github-mmgallery For readers in need, the main documents come from csdn The difference is that the project data in csdn is stored in MySQL and the project data is stored in Xml file. Courseware and learning video courses are from the second stage of MK net Java Engineer 2020.
1.MVC architecture mode
Early code: the display is coupled with the code. There are both html web pages and Java code in a page number. The code is chaotic and poor readability
<Ul> <% int max=Integer.parseInt() %> </Ul>
Model View Controller
The display is decoupled from the code and performs its own duties
- Model: it is responsible for the data required by the production business, that is, the specific business logic. The function class is * * service by default Java Naming.
-
The controller is the intermediary (adhesive) between the view and the model
-
The view is used to show the final result
MVC benefits:
- The software team is divided and cooperated, and the members perform their respective duties
- Layered development, display and data decoupling, easy to maintain
- Components can be replaced flexibly without affecting each other
2. Project code structure
2.1 engineering structure and development regulations
engineering structure
Package structure
MVC calling relationship
2.2 JavaBean
A reusable component in Java, which is the format requirement of a Java class and is usually used to store data
Format requirements:
- public class and provide the default constructor;
- All properties private
- Property is read and written through getter and setter methods
3. Implementation ideas
- Develop PaintingDao to read xml data and realize paging operation;
- Develop PaintingService service class and call PaintingDao;
- Develop PaintingController controller, call PaintingService, distribute request and respond at the same time
- Rewrite index HTML, using jsp technology to read paging
4. Preparation
4.1 create project
The data of the project is stored in xml file instead of database
4.2 developing XmlDataSource to obtain XML path
Mediation between Dao and XML
4.3 pagination ideas
Paging has two classes: xmldatasource Java and PageModel Java plus a JavaBean Painting java. XmlDataSource.java reads the XML and gets the data of the List storing the Painting object (using a static method of getRawData). PageModel gets data and
Get the page and rows parameters to get the key current page data List pageData. PaintingDao integrates two classes to form a data interface. The key is a paging function pagination:
public PageModel pagination(int page, int rows) { List<Painting> list = XmlDataSource.getRawData(); PageModel pageModel = new PageModel(list,page,rows); return pageModel; }
PaintingService rewrites Dao's paging function directly called by pagination, but only makes certain parameter judgment to avoid some exceptions
public PageModel pagination(int page, int rows, String...category) { if(rows == 0) { throw new RuntimeException("invalid rows parameter"); } if(category.length == 0 || category[0] == null) { return paintingDao.pagination(page,rows); } else { return paintingDao.pagination(Integer.parseInt(category[0]), page,rows); } }
Then go to paintingcontroller Get the parameters in Java, provide the default value, get the object of pageModel, and then set the parameters in req and forward the request to the corresponding index JSP page
index.jsp uses EI and JSTL to get pageModel
<ul> <c:forEach items="${pageModel.pageData}" var="painting"> <li> <img src="${painting.preview}" class="img-li"> <div class="info"> <h3>${painting.pname}</h3> <p> ${painting.description } </p> <div class="img-btn"> <div class="price"><fmt:formatNumber pattern="0.00" value="${painting.price}"></fmt:formatNumber></div> <a href="#" class="cart"> <div class="btn"> <img src="image/cart.svg"> </div> </a> </div> </div> </li> </c:forEach> </ul>
In realizing the classification preview function, rewrite pagination() in PaintingDao, add category parameter to classify it, and use variable parameters to return data in PaintingService:
public PageModel pagination(int page, int rows, String...category) { if(rows == 0) { throw new RuntimeException("invalid rows parameter"); } if(category.length == 0 || category[0] == null) { return paintingDao.pagination(page,rows); } else { return paintingDao.pagination(Integer.parseInt(category[0]), page,rows); } }
4.4 background management platform structure
Three column layout, providing oil painting list display, preview, modification, deletion and other operations, and providing file upload function for new works
With management HTML as a template, and then the content use request is displayed on the right.
Write a managementcontroller Java to manage all requests in a unified way, and use method to allocate them to each specific request processing method:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setCharacterEncoding("UTF-8"); //Call doGet for doPostd resp.setContentType("text/html;charset=utf-8"); String method = req.getParameter("method"); if(method.equals("list")){ this.list(req,resp); } else if(method.equals("delete")) { this.delete(req,resp); } else if(method.equals("show_create")){ this.show_createPage(req,resp); } else if(method.equals("create")){ this.create(req,resp); } else if(method.equals("show_update")) { this.showUpdatePage(req, resp); } else if (method.equals("update")) { this.update(req,resp); } } /** * Pagination display * @param req * @param resp * @throws ServletException * @throws IOException */ private void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String p = req.getParameter("p"); String r = req.getParameter("r"); if(p == null) { p = "1"; } if(r == null) { r = "6"; } PageModel pageModel = paintingService.pagination(Integer.parseInt(p),Integer.parseInt(r)); req.setAttribute("pageModel", pageModel); req.getRequestDispatcher("/WEB-INF/jsp/list.jsp").forward(req,resp); }
BTW: IDEA hot deployment is OK for both HTML and JAVA, as long as two points are set:
- Find the Edited Configuration from the Tomcat drop-down in the upper right corner of the IDEA interface, and set the on frame deation of the Server section to update classes and resources
- Debug in debug mode, which is a hot start.
When performing the preview function, the JS component of the SweetAlert2 dialog box is used (the source code on github needs to be compiled into the final usable JS file using node.js).
<script type="text/javascript"> //The dialog box displays a preview function showPreview(previewObj){ var preview = $(previewObj).attr("data-preview"); var pname = $(previewObj).attr("data-pname"); Swal.fire({ title: pname, html: "<img src='" + preview + "' style='width:361px;height:240px'>", showCloseButton: true, showConfirmButton: true }) } </script> <td> <a class="oplink" data-preview="${painting.preview}" data-pname="${painting.pname }" href="javascript:void(0)" onclick="showPreview(this)">preview</a> </td>
Upload file processing
- Using Apache Commons FileUpload component to realize upload function
- Encapsulating reusable js script to solve the problem of form verification
File upload form:
- form method="post"
- Form enctype = "multipart / form data"
- The form holds the file type input for file selection
After the file is uploaded, especially after enctype = "multopart / form data" is set in the form, it is different from the standard form post request. So use req The data obtained by getparameter () is null and cannot be obtained. Therefore, Apache Commons FileUpload component is required.
In this process, the logic is from front-end to back-end, from Controller to XmlDataSource, and in managementcontroller The create method in Java is as follows:
private void create(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //The data processing during file upload is completely different from the standard form //1. Initialize the FileUpload component FileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload sf = new ServletFileUpload(factory); //2. Traverse all form items FileItem try { List<FileItem> formData = sf.parseRequest(req); Painting painting = new Painting(); for(FileItem fi:formData) { if (fi.isFormField()) { System.out.println("Common input:" + fi.getFieldName() + ": " + fi.getString("UTF-8")); switch(fi.getFieldName()){ case "pname": painting.setPname(fi.getString("UTF-8")); break; case "category": painting.setCategory(Integer.parseInt(fi.getString("UTF-8"))); break; case "price": painting.setPrice(Integer.parseInt(fi.getString("UTF-8"))); break; case "description": painting.setDescription(fi.getString("UTF-8")); break; default: break; } } else { System.out.println("File upload item:" + fi.getFieldName()); //3. Save the file to the server directory String path = req.getServletContext().getRealPath("/upload"); System.out.println("Upload file directory:" + path); String fileName = UUID.randomUUID().toString(); String suffix = fi.getName().substring(fi.getName().lastIndexOf(".")); fi.write(new File(path,fileName + suffix)); painting.setPreview("upload/" + fileName + suffix); } } paintingService.create(painting);//New features //The reason why response redirection is used here is that the create here has no strong relationship with the list interface, but is just a required display page //The reason why request forwarding is used earlier is that the data in resp will be directly sent to the corresponding page for display. resp.sendRedirect("/mmgallery_war_exploded/management?method=list"); } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } }
4.4.6 Update Form
First, you have to backfill the data, save the state of the data on the new page, and modify it on this basis
- The biggest difference between modifying and adding is to load the original data before modifying
- Set the hidden hidden field on the modification page, save the id number and submit it with the form
- When updating XML, first obtain the original record by id, and then overwrite the update
Use id to backfill the data first, and then modify it later, omitted
4.4.7 delete form
public static void delete(Integer id){ SAXReader reader = new SAXReader(); Writer writer = null; try { Document document = reader.read(dataFile); List<Node> nodes = document.selectNodes("/root/painting[@id=" + id + "]"); if(nodes.size() == 0) { throw new RuntimeException("id=" + id + "No oil painting exists"); } Element p = (Element)nodes.get(0); // Delete operation p.getParent().remove(p); writer = new OutputStreamWriter(new FileOutputStream(dataFile),"UTF-8"); document.write(writer); } catch (Exception e) { e.printStackTrace(); } finally { if(writer != null) { try { writer.close(); } catch (IOException e) { e.printStackTrace(); } } reload(); } }
. . . . slightly
5. Summary
Temporary summary: during the Chinese new year, it may take more than 10 days to write all the functions of the whole project step by step with the video, which is regarded as the implementation of MVC architecture in Java Web. How to pass the request to the background, and then return the day after tomorrow to the front-end jsp. Moreover, there are a lot of implementations of JS code in it. It still takes a lot of time to digest and understand in the follow-up, and write it out temporarily first.