Write at the beginning:
I am a junior student, my main language is Java, and I am going to work as an intern in Hangzhou in my senior year. This article can be considered as a souvenir, but also leave some superficial ideas for students who lack project experience (who let the subject also benefit from open source code).
Project Introduction:
This is a tourism project based on SpringBoot, there are front introduction interface, there are background management system
Required basic knowledge: Mybatis+Spring+SpringMVC+SpringBoot+Thymeleaf+ Ajax +Spring Security
The project is fully annotated, without cumbersome configuration files
Project address: github.com/anPetrichor…
At the front desk page
The front desk access address: http://localhost:8080/travel
The background page
Backstage access address: http://localhost:8080/loginManage
Java part project structure
1. Config package: contains configuration classes and aspect classes
2. Controller package: Contains the controller class
3. Dao package: Contains dao interfaces
4. Domain package: Contains entity classes
5. Service package: Contains the Service interface and interface implementation class
6. Utils package: contains the class for uploading files
1. Configuration class in the project:
Visitors need to log in to change their profile picture, improve their information and so on, which is a basic function of the website
To implement this functionality, you need to use AOP programming in Spring
LoginAOP aspect classes: You must first log in to use user action functionality
The key to aspect classes: when to add what functionality to what methods
An Aspect, “Aspect,” is understood as an enhanced function
Pointcuts are understood as a set of target methods that need to be enhanced
Advice is understood as the execution time of a section
Before using user operations, we should judge whether the user is logged in. After login, we can perform subsequent operations. If the user is not logged in, it will jump to the login page
When and where to do everything is clear, then follow the logic to write down the matter, isn’t it
@aspect @Component public class LoginAOP {// execute user function @pointcut ("execution(*) com.travel.controller.UserDoController.*(..) )") public void loginPoint(){ } @Around("loginPoint()") public Object doBefore(ProceedingJoinPoint joinPoint) throws Throwable { //1. ServletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = requestAttributes.getRequest(); HttpSession session = Request.getSession (); //2. UserInfo userInfo = (userInfo) session.getAttribute("userInfo"); //3. If (userInfo == null){// If requestedWith is XMLHttpRequest, it is an Ajax request. String requestType = request.getHeader("X-Requested-With"); If ("XMLHttpRequest".equals(requestType)){// Return ajax data String loginResult = "{\"loginResult\":\"false\"}"; return loginResult; }else { return "redirect:/login"; }}else {// you have logged in to the executable target method Object proceed = joinPoint.proceed(); return proceed; }}}Copy the code
The @around surround enhancement method actually intercepts the execution of the target method, and the surround method must be executed before the target method can be executed
After the login succeeds or fails, the method can be passedAuthenticationFailureHandler
.AuthenticationSuccessHandler
If the login succeeds, the system is redirected to the background page, and if the login fails, the system is redirected to the login page
MyErrorPage implementationErrorPageRegistrar
To register different error types display different pages, the main role is to customize error pages such as 404
public void registerErrorPages(ErrorPageRegistry registry) { //400: ErrorPage errorPage_400 = new ErrorPage(HttpStatus.bad_request,"/error/400"); }Copy the code
MyMvcConfig implementationWebMvcConfigurer
, the configuration class isSpring
An internal configuration mode
Instead of writing to the Controller class, you can jump to the page using addViewControllers
You can also customize the static resource mapping directory in MyMvcConfig
SpringSecurity
Function: Configure authentication information and authentication policies
You can set permissions for urls
http.authorizeRequests().antMatchers("/travel/**").permitAll()
Copy the code
UserInfoService is a custom class that is used to retrieve user information from the database.
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userInfoService);
}
Copy the code
When AuthenticationManager authenticates the user, it obtains the user identity from the userInfoService and compares it with the user identity from HTTP. If the comparison is successful, the subsequent operations are allowed.
Entity class
(1) booking hotel table (2) round table (3) food shop table (4) destination table (5) food table (6) hotel table (7) message table (8) order table (9) permission table (10) route table (11) route picture table (12) scenery table (13) user information table
It’s a very clear system, and I won’t draw the ER diagram
Dao interface: Defines methods to operate on the database
Service interface and interface implementation class: Defines methods and method implementations
Controller class: Defines the method that handles the request
The above code is too long to mention the UserInfo operation separately
Public class UserInfo {private Integer ID; Private String username; // Private String username; // User name private String password; // User password private String phoneNum; // User phone number private String email; Private String url; // User profile address private Integer status; Private String statusStr; Private Integer gender; // Private String intro; Private List<Role> roles; // All permissions for the user //get,set // override toString}Copy the code
Just define the attributes you need
/ / @ the dao layer Mapper public interface UserInfoDao {/ / front desk travel website login @ the Select (" Select * from the user where the username = # {username} the and password=#{password}") public UserInfo findUser(@Param("username") String Username, @Param("password") String Password) throws Exception; }Copy the code
Dao layer defines a method to query the user name and password, used for the front page login, query the user name and password from the database, when the database information is consistent with the input information, the login is successful
Column =” database field name “property=” entity class attribute” and call the corresponding method using @One or @many
Public Interface UserInfoService extends UserDetailsService {public UserInfo findUser(String) extends UserDetailsService {public UserInfo findUser(String) username, String password) throws Exception; } @service public class UserInfoServiceImpl Implements UserInfoService {@resource private UserInfoDao userInfoDao; @Override public UserInfo findUser(String username,String password) throws Exception { return userInfoDao.findUser(username,password); }}Copy the code
The Service class invokes the DAO interface to implement the login function
/ / SpringSecurityController definition method to handle the login request/login/user performs operations @ RequestMapping (value = "/ login. Do", method = RequestMethod. POST) @ResponseBody public Object doLogin(@RequestParam("username") String username, @RequestParam("password") String password, HttpSession session) throws Exception{ HashMap<String,String> loginResult = new HashMap<String, String>(); UserInfo userInfo = userInfoService.findUser(username,password); if (userInfo ! = null){if (userinfo.getStatus () == 1){// The user name and password are correct and the account status is available in session.setattribute ("userInfo",userInfo); loginResult.put("loginResult","true"); }else {// Prohibit loginresult. put("loginResult","forbid"); }}else {// LoginResult. put("loginResult","false"); } return JSONArray.toJSONString(loginResult); }Copy the code
The Controller class defines the doLogin method to respond to the login.do request
The session object does:
The server creates a session object for the browser. When it needs to store user data, the server application can write the user data to the user’s browser-exclusive session. When the user accesses another application using the browser, the other application can retrieve the user’s data from the user’s session and serve the user. The login information is saved in the session, which can be used as the basis for whether the user logs in or not
Tools: Upload files
public class UploadFileUtils { public static String uploadImgFile(MultipartFile file,String param) throws IOException { / / 1. String originalFilename = file.getorigInalFilename (); String originalFilename = file.getorigInalFilename (); / / 2. Obtain the file suffix String suffixName = originalFilename. Substring (originalFilename. LastIndexOf (". ")); String newFilename = uuid.randomUuid ().toString().replace("-","") + System.currentTimemillis () + suffixName; String localFilename = "F:\\Springboot\\18_jxnu\\ SRC \\main\\resources\\static\\images\\" + param + File.separator + newFilename; File desFile = new File(localFilename); //5. //6. Save the uploaded file with a new name to the server file.transferto (desFile); System.out.println(" Upload to server successfully "); //7. Return newFilename; //8. Return newFilename; }}Copy the code
The Spring framework uses the MultipartFile class to help you quickly implement file uploading in the form of a form
The getOriginalFileName method gets the full name of the file, including the name of the file + the extension of the file
The transferTo method is used to transfer the received file to the given destination path
Implementation steps:
The front end passes in the file, obtains the file, renames the file name, saves to the required path, saves the picture
The front page
Login page: The login page provides a message to the user when the user name or password is incorrect. After a successful login, the user is redirected to the main page
A tipString is used to prompt the user when the user name or password is blank
This is done by defining the ValidateTip function
function validateTip(element,css,tipString,status){
element.css(css);
element.attr("placeholder",tipString);
element.attr("validateStatus",status);
}
Copy the code
If the user name is null, change the INPUT CSS style to red, tipString to “The user name cannot be null”, and status to false to check whether the user name is null. The same is true for the password.
var username = $("#username"); username.on("blur",function () { if (username.val() == null || username.val() == ""){ ValidateTip (username,{"border":"2px solid red"}," username ", "false"); }});Copy the code
When the login button is clicked, Ajax makes a login.do request to the server
When the result returned to the client is true, the login is successful and the current page opens /travel.
$.ajax({ type:"POST", url:"/login.do", data:{"username":username.val(),"password":password.val()}, dataType:"json", success:function (data) { if (data.loginResult == "true"){ location.href = "/travel"; }}});Copy the code
If false is returned from the client, the login failed and an error page is returned.
if (data.loginResult == "false"){ error.show(); error.css("border","2px solid #ea6f5a"); Error.html (" Incorrect user name or password "); }Copy the code
The registration page has more constraints on the length and type of the user name and password than the login page. The subject uses regular expressions to achieve this function
/ / user name regular expression, only by alphanumeric _ -, 5-16 var pattern = / ^ [a zA - Z0 - _ - 9] {5 dec} $/; / / password (6-24, including letters, Numbers, special characters [$@! #? % * &]) var pattern = / ^ [a - zA - Z0-9. $@! #? % * &] 6, 24} {$/; Regular expression var patrn = / / phone number / ^ (13 [0-9] [0-9] | | 15 18 [0-9]) \ d {8} $/;Copy the code
Use ajax requests to determine whether the user name and number are used
If it is not in use, normal registration operations can be performed
Ajax judgments are implemented in a similar way to /login.ajax above
Top navigation bar
The navigation bar is divided into two parts: the navigation bar on the left and user information on the right
Th :fragment="traveltop"// Left th:fragment="userInfo"// RightCopy the code
Th :if="${session.userinfo ==null}" th:if="${session.userinfo! =null}// Indicates that you are logged inCopy the code
If the user has logged in, the personal center page is displayed. If the user has not logged in, the original fragment is displayed
Home Page The home page uses the each loop to read data and display the results
<div th:each="destination:${destinations}">
<img th:src="@{${destination.url}}">
</div>
Copy the code
The Controller layer uses the Service layer findSixDestination method to find six hot spots from the database
@RequestMapping(value = "/travel",method = RequestMethod.GET)
public String travel(Model model) throws Exception{
List<Destination> destinations = destinationService.findSixDestination();
model.addAttribute("destinations",destinations);
return "user/travel";
}
Copy the code
Attractions Details Page The video tag in HTML needs to be formatted to play properly
Recommended Route page
The page initiates a request, the controller calls the Service method to process the request, and the Service method in turn calls the DAO interface, which queries the database data.
@select (" Select * from route order by heat desc") @results ({@result (id = true,property = "id",column = "id"), @Result(property = "routePhotoList",column = "id",javaType = List.class,many = @Many(select = "com.travel.dao.RoutePhotoDao.findRoutePhotoByRId")) }) public abstract List<Route> findAllByHeat() throws Exception;Copy the code
Free-travel page
Fuzzy query for database information, other steps are the same as the above page
@select (" Select * from route where routeDesc like concat(concat('%',#{month},'%')) and price >= #{minPrice} and price < #{maxPrice} and time >= #{minDay} and time <= #{maxDay} and routeDesc like concat(concat('%',#{dest},'%'))")Copy the code
Hotel Booking page
@select (" Select * from hotel where destId=#{destId}")Copy the code
FindHotelsByDestName. Ajax after find the data returned to find the hotel information
search.on("click",function () { $.ajax({ type:"GET", url:"/travel/hotel/findHotelsByDestName.ajax", data:{"destName":destName.val()}, dataType:"json", success:function (data) { var str = ""; if (null ! = data && "" ! = data){ $.each(data,function (index,hotel) { str += "<div class=\"row h-item\">" + "<div class=\"col-lg-3\">" + "<img src=\"" + hotel.url + "\" class=\"img-rounded\">" + "</div>" + "<div class=\"col-lg-9\">" + "<div class=\"h-info\">" + "< h4 >" + hotel name + "< / h4 >" + "< p >" + hotel. English + "< / p >" + "< p >" + hotel. HotelDesc + "< / p >" + "< p > position: "+ hotel.location + "</p>" +" " + hotel.price + "</p>" + '<button hotelId=\"' + hotel.id + '\"' + 'hotelPrice=\"' + hotel.price + '\"' + "class=\"btn BTN - warning book - hotel \ "> reservations now < / button >" + "< / div >" + "< / div >" + "< / div >" + "< hr >"; });Copy the code
Background management system
Background management system is a visual data to add, delete and check the page
This part is so easy to write the SQL completely
When the amount of background data is large, pageHelper plug-in can be used to paging the data
Write at the end:
The writing level and code level are limited, if there are mistakes, please forgive me.