Full record of dark horse travel website

1, Project import

  1. Click maven on the side (if not, you can find it in view - > tool window), click the plus sign, and select the pom.xml document in the file to import

  2. First preview the static page

    Start mode 1:


    Start mode 2: add a start mode and click the green triangle to start

2, Technology selection

  1. web:
    servlet: front end controller
    HTML: data presentation
    Filter: filter
    BeanUtils: data encapsulation
    Jackson: json serialization tool

  2. service:
    Java email: sending files in Java
    redis: nosql memory data
    jedis: redis client of Java

  3. Dao
    Mysql: Database
    Druid: database connection pool
    jdbc template: tool class of jdbc

3, Create database

4, Realize login, registration and exit

Call graph of each layer:

Registration: use js to complete form verification in html and ajax to complete form submission
Successful registration, jump to the success page
Registration failed, jump to the failed page

servlet: RegisterServlet
(0. The setting code has been completed by using the unified filter)
1. Obtain data
2. Encapsulate User objects
3. Call service to complete registration
4. According to the service return, the prompt message is:
Convert prompt to json
Set corresponding header: contentType

service:
registerUser(User user)
Call dao to query the user according to the user name
Exists, return false
Does not exist, call dao to save user information

Dao:
1. Query user information findByUsername(string username) according to user name;
2. Save user information

Asynchronous Ajax submission form:
$(this).serialize() submit the data in the form in the format of username = XXX & & password = 123
Asynchronous submission is used to obtain the data responded by the server. The foreground uses html as the view layer. It cannot directly obtain the value from the domain object related to the servlet, but only through Ajax

**

When writing, you write a stupid question wrong, resulting in the inability to access the home page, that is, the annotation name is written wrong, and the webServlet is written as webFilter, resulting in the inability to access the web page 404

**

login.jsp

Simple jquery login authentication

<script type="text/javascript">
        //Check user name format
        function checkUsername() {
            var username = $("#username").val();
            var reg_username = /^[A-Za-z_0-9]{4,20}$/;
            var flag = reg_username.test(username);
            if(flag){
                $("#username").css("border","");
            }
            else{
                alert("User name format error");
                $("#username").css("border","1px solid red");
                //$("#addusername").html("user name format error")// Remember to add a new html format
            }
            return flag;
        }
        //Check password format
        function checkPassword(){
            var password = $("#password").val();
            var reg_password = /^[A-Za-z_0-9]{4,20}$/;
            var flag = reg_password.test(password);
            if(flag){
                $("#password").css("border","");
            }
            else{
                alert("Password format error");
                $("password").css("border","1px solid red");
                //$("#addusername").html("user name format error")// Remember to add a new html format
            }
            return flag;
        }
        //Check for correctness when submitting
        $(function () {
            $("#form").submit(function () {
                if(checkPassword()&&checkUsername()){
                    return true;
                }
                return false;
            })
            //When the focus is lost, judge the format
            $("#username").blur(checkUsername);
            $("#password").blur(checkPassword);
        })
    </script>

Add a form in the body and pass the value into the Servlet

<form id="form" name="form" action="indexServlet">
        <div>
            user name:
            <input type="text" id="username" name="username" placeholder="enter one user name">
        </div>
        <div>
            password:
            <input type="text" id="password" name="password" placeholder="Please input a password">
        </div>
        <div>
            <input type="submit" id="login" name="login" value="Sign in">
        </div>
    </form>

You can use ${error} to receive error messages passed in the background

<!--Get the error message from the background-->
<div>${error}</div>

LoginServlet

//Set encoding
req.setCharacterEncoding("utf-8");
//Get user input data
String username = req.getParameter("username");
String password = req.getParameter("password");

//Determine whether the user name and password are correct
if(username.equalsIgnoreCase("zhangsan")&&password.equalsIgnoreCase("123456")){
    //If the user name and password are correct, jump to the main page
    req.getRequestDispatcher("/home.jsp");
}else{//The user name and password are incorrect, and the error information is stored
    req.setAttribute("error","Wrong user name or password");
    //Carry the error information and forward it to the login page
    req.getRequestDispatcher("/index.jsp").forward(req,resp);
 }

5, Mail activation of registration page

Reason: to ensure that the email filled in by the user is correct. Can push ads
Send mail: written using the emailutil tool class
Activation mail:
For the database, activation is to change the status status to the active status
Mail activation analysis:

Don't write code under return. Java reports an unreachable statement error
See connection for details: https://blog.csdn.net/qq_33915826/article/details/79246482

6, Login


After logging in, the individual user name is dynamically displayed

header.html

<script>
        $(function () {
            $.get("findUserServlet",{},function (data) {
                //{uid:1,name:"yangcichen"}
                var msg = "welcome back,"+data.name;
                $("#span_username").html(msg);
            })
        })
</script>

Asynchronous interaction
When the whole page is accessed, use ajax to access the server to query the information

7, Exit

First of all, we should think about when it is called login success?
If the login is successful, there is a user in the session
Then the exit function is realized:
header.html

<a href="javascript:location='exitServlet';">sign out</a>

1. Access the servlet and destroy the session

req.getSession().invalidate();

2. Jump to the login interface, jump to the page, and use redirection (the path writing method is virtual directory)

resp.sendRedirect(req.getContextPath()+"/login.html");

8, Optimizing Servlet -- BaseServlet

Optimization method: reduce the number of servlets and optimize them into one module and one servlet

Write a module servlet to let the servlets of various functions inherit
The module servlet inherits the HTTP servlet

"this" – who calls me and who I represent

The error report indicates that there is no matching method:

Reason: the method is declared as protected and does not have permission when accessing
resolvent:

① Ignore the access permission modifier when accessing. This method will ignore all methods

//Ignore access modifier
Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class);
//Execution method
//Violent reflex
method.setAccessible(true);
method.invoke(this,req,resp);

② Directly change the method permission modifier to public, which is conducive to the protection of other private methods

Another low-level error was made - the findOne name was written incorrectly, causing the browser to not find it

9, Display of tourism data

Classified data display:
It turned out to be false data, which was dynamically generated from the background in the later stage

<div class="navitem">
     <ul class="nav">
         <li class="nav-active"><a href="index.html">home page</a></li>
         <li><a href="route_list.html">admission ticket</a></li>
         <li><a href="route_list.html">hotel</a></li>
         <li><a href="route_list.html">Hong Kong Ticket</a></li>
         <li><a href="route_list.html">Outbound travel</a></li>
         <li><a href="route_list.html">Domestic tour</a></li>
         <li><a href="route_list.html">Hong Kong and Macao tour</a></li>
         <li><a href="route_list.html">Group customization</a></li>
         <li><a href="route_list.html">Global free travel</a></li>
         <li><a href="favoriterank.html">Collection ranking</a></li>
     </ul>
 </div>

Information in database:

Code optimization: after each page loading, the page classification data will require the database to load again, which will put great pressure on the database, and the classified data will not change frequently, so redis can be used to cache this data.

The order in which the data is expected to be stored in the database is the data displayed

10, Tourism routes are displayed in different pages

After clicking on different categories, the tourist routes are inconsistent.
Classification and tourist routes are one to many

How to carry cid:

	//Background service
 	Set<Tuple> categorys = jedis.zrangeWithScores("category", 0, -1);
	//2. Judge whether the query set is empty
	List<Category> cs=null;
	//2.1 is null, first visit
	if(categorys==null||categorys.size()==0){
	    //Query from database
	     cs = categoryDao.findAll();
	     //Store the collection in the key of the category in redis
	    for (int i = 0; i < cs.size(); i++) {
	        //Storage zadd
	        jedis.zadd("category",cs.get(i).getCid(),cs.get(i).getCname());
	    }
	}else{
	    //2.2 if it is not empty, save the set data into the list
	    //The front end needs List, but this method returns set for format conversion
	    cs=new ArrayList<Category>();
	    for (Tuple tuple:categorys) {
	        Category category = new Category();
	        category.setCname(tuple.getElement());
	        category.setCid((int)tuple.getScore());
	        cs.add(category);
	    }
	}

front end:

for(var i=0;i<data.length;i++){
      var li = '<li><a href="favoriterank.html?cid='+data[i].cid+'">'+data[i].cname+'</a></li>';
      lis += li;
}

How to get cid:

<script>
    $(function () {
        var search = location.search;
        //alert(search);
        //Cut the obtained string [? cid=5] to get 5
        var cid = search.split("=")[1];
    })
</script>

Obtain different travel route data according to cid:

11, Tourist route name query

1. Transfer of query parameters
From route_list?cid=5 pass route_list?cid=5&rname=xxx
Pass xxx
First, get the rname entered by the user

/*header.html*/
$("#search-button").click(function () {
       //The background performs fuzzy matching according to this name
       var rname = $("#search_input").val();
       //alert(rname);
       var cid = getParameter("cid");
       //alert(cid);
       //Jump path http://localhost/travel/route_list.html?cid=5
       //Then splice rname=xxx
       location.href="http://localhost/travel/route_list.html?cid="+cid+"&rname="+rname;
})
/*route_list.html*/
//The getParameter() method encapsulates the character cutting function for itself
//Get cid
var cid = getParameter("cid");
//Get rname
var rname = getParameter("rname");
if(rname){
    //Decoding method. The obtained rname is a url and needs to be decoded
    rname=window.decodeURIComponent(rname);
}

2. Modify the previous background code
Servlet,Service,Dao

tomcat7 transfers the value from the front end to the background. The solution is:

//Tomcat7, the get request is garbled
rname = new String(rname.getBytes("iso-8859-1"),"utf-8");

There is a problem that data cannot be queried by directly clicking the relevant route to switch the route:

Pass value load(5,2, 'null')

Solution link
When rname is empty, the "null" string passed to RouteServlet by the front end is not null
Therefore, in the place of judging whether the parameter in RouteDaoImpl has a value, rname is queried as a "null" keyword (with a value), while the database does not have a tourism route with a keyword of "null", so 0 records are returned, resulting in an error.
It is similar to the previous judgment that cid is' null '.

12, View tour route details


Error in picture display:

Through front-end breakpoint debugging, it is found that the tag uses the style="display:none; attribute
If its attribute is deleted, the picture can be displayed normally, but the displayed data css is incorrect
Judge i that there are 4 displays on each page, and more than 4 are hidden

//Traverse routeImgList
for (var i = 0; i < route.routeImgList.length; i++) {
   if(i>=4){
       var astr='<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'" style="display:none;">\n' +
           '             <img src="'+route.routeImgList[i].smallPic+'">\n' +
           '             </a>'
   }else {
       var astr='<a title="" class="little_img" data-bigpic="'+route.routeImgList[i].bigPic+'" >\n' +
           '             <img src="'+route.routeImgList[i].smallPic+'">\n' +
           '             </a>'
   }

   ddstr+=astr;
}

13, Tourist route collection function

After the page is loaded, send an ajax request to query the database to see whether the user has collected the line
Display different styles according to query results

Dynamic display of collection words
Click the favorite button:

Bind the click event to the button, click the button, and call the addFavorite() method in js:

<a class="btn" id="favorite" onclick="addFavorite();"><i class="glyphicon glyphicon-heart-empty" ></i>Click collection</a>

Tags: Java Maven Tomcat servlet intellij-idea

Posted on Sun, 05 Dec 2021 00:12:40 -0500 by dhorn