[dark horse tourism network] project completion + unfinished function realization + personal summary + bug record

Source address: at the bottom of this article!

1、 Project configuration problem

1. [Maven project directory structure]

The directory form of the project file created at the beginning may be wrong. The idea has obvious requirements for the directory structure, which can be modified by the following methods. Of course, it can also be used in other cases;

2. Modify directory attribute

Later, it was found that you can directly right-click the directory and select make directory as. The effect is the same.

3. [set web source directory]

4. [Maven lower version conflicts with servlet 3.0]

Servlet 3.0 is used in the video The version after 0 uses annotation configuration. I used to use annotation configuration before. I want to try using XML configuration to practice. However, during the process of converting XML to annotations, I encountered some problems, mainly the conflict between servlet version and Maven warehouse version? I'm not clear about the details. It's too real. The whole process is vague. There are frequent bugs. I've tried many methods. I really don't know which method works.

The following content only records my own error correction process. First, I go to the code file in the video to check the deviation: direct locking is the version problem of servlet, servlet3 Annotations can only be used after 0, and I use 2.5.

Then, I refer to this blog: Maven creates a webapp skeleton, can't use @ webservlet to implement the annotation configuration solution, and modifies the web.xml of the jar package in Maven warehouse XML content may be a problem of my operation, but it doesn't work.

Then I saw a method on a forum to re specify the version of XML. [after several tests, it seems that it has little to do with this]

Then in POM Add servlet3. XML For dependencies after 0, it should be noted that the scope should be specified as provide, otherwise conflicts may occur. [be sure to find and fill in the correct coordinates. Once I wrote servlet API in artifactid, but I couldn't download it]

        <!--Servlet-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

Conflict errors like this (both of the following are because the scope does not specify privided, because it is added successfully)

com. travel. web. filter. CharacterFilter cannot be cast to javax. servlet. Filter。

javax. servlet. ServletException: java. lang.LinkageError。

You will encounter a lack of Java EE in the middle. The annotation package depends on the missing error. You can add it according to the prompt.

The above is what I learned from the web The whole process from XML to annotation configuration is a little bumpy, but there may be more ideas in case of such problems in the future.

5. [console output garbled code solution]

settings->Build,Execution,Deployment->Build Tools->Maven->Runner。

Set VM option parameter and specify virtual machine character set: - dfile Encoding = GB2312. If not, you can set other scales.

2、 Foreground code

1. [send asynchronous request]

//校验通过,ajax发送请求,提交表单数据  $("#registerForm").serialize()
$.post("registerUserServlet",$(this).serialize(),function (data) {

    if(data.flag){
        //注册成功,跳转成功页面
        location.href= "register_ok.html";
    }else{
        //如果错误,需要重新对验证码servlet请求一次,不然会导致会话中的验证码消失,图片虽然存在,但码已经没有了
		document.getElementById("check_img").src= "checkCode?"+new Date().getTime();
        //注册失败,给errormsg添加提示信息
        $("#error_msg").html(data.errorMsg);
    }
})

2. [verify mobile phone number format]

var reg_telephone = /^1(3|4|5|7|8)\d{9}$/;

3. [check email format]

var reg_email = /^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/;

4. [loss of focus event]

Note that the function name is passed in as a function object without ().

$("#username").blur(checkUsername);

5. [front and rear end interaction]

Encapsulating information as an object is worth learning.

public class ResultInfo implements Serializable {
    private boolean flag;//后端返回结果正常为true,发生异常返回false
    private Object data;//后端返回结果数据对象
    private String errorMsg;//发生异常的错误消息
}

6. [onclick() event in HTML]

reference resources: https://blog.csdn.net/ywl570717586/article/details/53130863 , the blog is below the split line.

7、【jackson】

Using mapper object to manipulate JSON data

import com.fasterxml.jackson.databind.ObjectMapper;

//将info对象序列化为json,返回客户端
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(info);
//将json数据写回客户端
//设置content-type
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);

8、【 check@R_244_2419 @】

When the value attribute is not specified, the past value passed is on!!!

9. [obtain parameters spliced in url]

//根据传递过来的参数name获取对应的值
function getParameter(name) {
    var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)","i");
    var r = location.search.substr(1).match(reg);
    if (r!=null) return (r[2]); return null;
}

3、 Use of tool classes

Use [mailutils] to complete email sending, but you have to apply to start the service in the mailbox settings.

Use [UUID tools] to complete the generation of random activation code.

Use [jedisutils] to obtain the redis client and operate the redis database.

Encapsulate the Druid connection pool with [JDBC utils] and return the data source object.

4、 Path distribution idea

Refer to the service method of httpservlet for path distribution of requests. Different methods are used to complete different functions similar to those completed by servlets. It really benefits a lot. Looking back, we need to define so many servlets. Now they are completely encapsulated in a userservlet. Wonderful.

[distribute servlet]

try {
    Method method = this.getClass().getmethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
    //调用方法
    method.invoke(this,req,resp);

} catch (NoSuchMethodException | illegalaccessexception | InvocationTargetException e) {
    e.printStackTrace();
}

Error: Java lang.NoSuchMethodException

Reason: the calling method is protected.

solve:

5、 Database problems

1. [connection problem]

com. MysqL. jdbc. exceptions. jdbc4. CommunicationsException: Communications link failure

Cause of error: it may be because the MySQL service is not started. Open services MSc, just open mysql.

A similar problem is that the redis server is not enabled: redis clients. jedis. exceptions. JedisConnectionException: java. net. socketTimeoutException: connect timed out。

2. [MySQL statement]

Error: every derived table must have its own alias

SELECT COUNT(*) FROM ( select * from department) AS aa; -- 语法如此,需要给子查询的表加上别名。

3. [cache optimization]

Some resources will re request database data to load every time the page is loaded, which puts great pressure on the database, and these data will not change frequently. Cache optimization can be carried out.

https://blog.csdn.net/Sky_QiaoBa_Sum/article/details/105167978

6、 Personal optimization of some minor deficiencies of the project

1、【Alibaba Java Coding Guidelines】

After downloading the plug-in, I found that the comments I originally wrote were so unprincipled. Ha ha, this thing is a devil for people with obsessive-compulsive disorder.

2. [extracted verification code verification function]

    private boolean checkCode(HttpServletRequest request,HttpServletResponse response) throws IOException {
        //验证码校验
        String check = request.getParameter("check");

        HttpSession session = request.getSession();
        String checkCodeServer = (String) session.getAttribute("checkCode");

        //保证验证码只能使用一次
        session.removeAttribute("checkCode");
        //验证码不相等
        if(checkCodeServer == null||!checkCodeServer.equalsIgnoreCase(check)){
			//对用户输入验证码进行判断
            if("".equals(check)){
                info.setErrorMsg("验证码不能为空");
            }else {
                info.setErrorMsg("验证码错误");
            }
            info.setFlag(false);
            response.setContentType(JSON_CONTENT_TYPE);
            String s = mapper.writeValueAsString(info);
            response.getWriter().write(s);
            return false;
        }
        return true;
    }

3. [about listfull and list. Size (0)]

This is also a problem I think when I look back at my code. I once saw similar Science in some WeChat official account.

Sometimes the Dao layer may cause the list set to be empty. For example, if the list is not queried, if NULL is returned, the corresponding non null judgment needs to be made in the service layer. Sometimes it may be forgotten. My initial idea was to initialize an empty ArrayList. List < category > List = new arraylist();

![优化](E:\1JavaBlog\maven\pic\优化.png)![优化](E:\1JavaBlog\maven\pic\优化.png)    @Override
    public List<Category> findAll() {
        //List<Category> list = Collections.emptyList();
        List<Category> list = new ArrayList<>();
        try{
            String sql = "select * from tab_category";
            list = template.query(sql,new BeanPropertyRowMapper<>(Category.class));
        }catch (Exception e){
        }
        return list;
    }

In the process of searching data, it is found that the collections collection class has a special method to generate empty collections, such as list < category > List = collections emptyList();, Looking at his source code, we can find that it actually creates a static internal class object private static class emptylist < E >. More specifically, the generated list does not have the familiar add, remove and other methods. If you perform these operations on it, you will directly throw an unsupported operationexception.

https://blog.csdn.net/Sky_QiaoBa_Sum/article/details/105168546

7、 Implement unfinished functions

1. [when loading is completed, make the large picture the first one]

2. [add information with empty verification code and refresh the verification code]

Avoid inconsistent pictures and texts.

3. [add my collection and paging function]

<a href="javascript:void(judgeUser())" id="myFavorite" class="collection">我的收藏</a>

//点击我的收藏
judgeUser = function (){
    //未登录
    if(user == null){
        alert("您尚未登录,请登录!")
        location.href = "http://localhost/travel/login.html";
    }else{
        //已登录a
        // alert(user.uid);
        var uid = user.uid;
        // http://localhost/travel/route/pageFavorite?uid=7
        location.href = "http://localhost/travel/myfavorite.html?uid=7";
    }
}

4. [automatic login function added]

Using cookie technology, the account password is stored on the client to realize automatic login.

5. [added popular recommendation function]

Add popular recommendations and connect route details.

6. [the display function of three types of tourist routes on the home page is added]

But the corresponding style above is true. I don't know where to change it. After debugging, I found that it's right to activate the active style when clicking. The bug lies in the three columns on the left and the font on the right. I hope you can teach me how to fix it! Otherwise it would be too hard.

Based on this part, some displays are optimized:

                    <ul class="jx_tabs" role="tablist">
                        <li onclick="popu()" role="presentation" class="active">
                                <a href="#popularity" aria-controls="popularity"
                                   role="tab" data-toggle="tab">人气旅游</a>
                        </li>
                        <li onclick="newest()" role="presentation">
                                <a href="#newest" aria-controls="newest" role="tab"
                                   data-toggle="tab">最新旅游</a>
                        </li>
                        <li onclick="theme()" role="presentation">
                                <a href="#theme" aria-controls="theme" role="tab"
                                   data-toggle="tab">主题旅游</a>
                        </li>
                    </ul>

CSS style change:

        <style >
            .jx_tabs li  a {
                display: inline-block;
                flex: 1;
                flex-direction: row;
                position: relative;;
            }
            .jx_tabs .active a {
                background-color: #ffc900;
                color: #fff;
            }
        </style>

7. [added display page and query function of collection ranking list]

This part consumes a lot of time in the SQL statement part. The table relationship is as follows:

My idea is, first according to the tab_ The rids in favorite are grouped, and then the number of each rids is calculated, that is, the number of user collections. They are arranged in descending order to generate a new sub query table. Then in the tab_ Find the route with the same rid as the sub query table rid in the route, and conduct the where sub query to fuzzy match the route name and amount. Finally, you can obtain:

The routes are sorted in descending order by the number of collections, and fully meet the search conditions.

    @Override
    public List<Route> findRouteByRangePage(int start,int pageSize,String rname,int first,int last) {
        //String sql = "select * from tab_route where cid = ? limit ?,?";

        String sql = "SELECT * FROM (SELECT * FROM (SELECT rid,COUNT(rid) AS COUNT FROM tab_favorite " +
                "GROUP BY rid ORDER BY COUNT(rid) DESC)AS aa)AS bb,tab_route t WHERE t.rid = bb.rid ";
        StringBuilder sb = new StringBuilder();
        //条件们
        List params = new ArrayList();
        //判断参数是否有值
        if(rname!=null&&rname.length()>0){
            sb.append("and t.rname like ?");
            params.add("%"+rname+"%");
        }
        if(first!=0){
            sb.append("and t.price > ? ");
            //添加?对应的值
            params.add(first);
        }
        if(last!=0){
            sb.append("and t.price < ? ");
            //添加?对应的值
            params.add(last);
        }
        //分页
        sb.append("limit ?,? ");
        sql += sb.toString();
        params.add(start);
        params.add(pageSize);
        return template.query(sql,new BeanPropertyRowMapper<>(Route.class),params.toArray());
    }

It's just cumbersome to complete the requirements in front of you. I don't know if there is a better scheme. Welcome to communicate.

8. [a little bug]

if (rname === "" && first === "" && last === "") {
    favoriteRank(null,null,null)
} else if (rname === "" && first === "") {
    favoriteRank(null,last)
} else if (rname === "") {
    favoriteRank(null,last)
} else {
    favoriteRank(null,last)
}

In this way, the following problems can be solved:

@H_ 953_ 502@

8、 Personal reflection

9、 Follow up supplement

A small partner found a small bug after getting the project, as follows:

Then: XXX is not defined appears

Because in the function parameters, when splicing, you need to enclose the parameters in single quotes.

You can also optimize:

var first_param = rname ===""?null:rname;
var second_param = first ===""?null:first;
var thrid_param = last ===""?null:last;
favoriteRank(null,first_param,second_param,thrid_param)

This can be solved.

10、 Source download

The previous code cloud link failed, probably because I mistakenly set the warehouse to private. Then I uploaded it to the code cloud warehouse again, and the small partners who need the code can download it.

Download address: https://gitee.com/tqbx/itheima-travel-demo

If you think this article is helpful to you, please use your little hand to praise it, ha ha.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>