当前位置:

首页 > 编程开发 > springboot用户数据怎么修改

springboot用户数据怎么修改

修改密码1用户-修改密码-持久层1.1规划需要执行的SQL语句用户修改密码时需要执行的SQL语句大致是:UPDATEt_userSETpassword=?,modified_user=?,modified_time=?WHEREuid=?在执行修改密码之前,还应检查用户数据是否存在、并检查用户数据是否被标记为“已删除”、并检查原密码是否正确,这些检查都可以通过查询用户数据来辅助完成:SELECT*FROMt_userWHEREuid=?1.2接口与抽象方法在UserMapper接口添加updatePass

    修改密码

    1 用户-修改密码-持久层

    1.1 规划需要执行的SQL语句

    用户修改密码时需要执行的SQL语句大致是:

    UPDATE t_user SET password=?, modified_user=?, modified_time=? WHERE uid=?

    在执行修改密码之前,还应检查用户数据是否存在、并检查用户数据是否被标记为“已删除”、并检查原密码是否正确,这些检查都可以通过查询用户数据来辅助完成:

    SELECT * FROM t_user WHERE uid=?
    1.2 接口与抽象方法

    在UserMapper接口添加updatePasswordByUid(Integer uid,String password,String modifiedUser,Date modifiedTime)抽象方法。

    用注解来简化xml配置时,@Param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中。@Param("参数名")注解中的参数名需要和sql语句中的#{参数名}的参数名保持一致。

    /**
     * 根据uid更新用户的密码
     * @param uid 用户的id
     * @param password 新密码
     * @param modifiedUser 最后修改执行人
     * @param modifiedTime 最后修改时间
     * @return 受影响的行数
     */
    Integer updatePasswordByUid(
    		@Param("uid") Integer uid, 
    		@Param("password") String password, 
    		@Param("modifiedUser") String modifiedUser, 
    		@Param("modifiedTime") Date modifiedTime);
    
    /**
     * 根据用户id查询用户数据
     * @param uid 用户id
     * @return 匹配的用户数据,如果没有匹配的用户数据,则返回null
     */
    User findByUid(Integer uid);
    1.3 配置SQL映射

    1.在UserMapper.xml中配置updatePasswordByUid()、findByUid()抽象方法的映射。

    
    
    	UPDATE
    		t_user 
    	SET
    		password = #{password},
    		modified_user = #{modifiedUser},
    		modified_time = #{modifiedTime} 
    	WHERE
    		uid = #{uid}
    
    
    
    
    	SELECT
    		*
    	FROM
    		t_user
    	WHERE
    		uid = #{uid}
    

    2.在UserMapperTests中编写并执行单元测试。

    @Test
    public void updatePasswordByUid() {
    	Integer uid = 7;
    	String password = "123456";
    	String modifiedUser = "超级管理员";
    	Date modifiedTime = new Date();
    	Integer rows = userMapper.updatePasswordByUid(uid, password, modifiedUser, modifiedTime);
    	System.out.println("rows=" + rows);
    }
    
    @Test
    public void findByUid() {
    	Integer uid = 7;
    	User result = userMapper.findByUid(uid);
    	System.out.println(result);
    }

    2 用户-修改密码-业务层

    2.1 规划异常

    1.用户在修改密码前,需要检查用户数据是否存在及是否被标记为“已删除”。如果检查不通过则应抛出UserNotFoundException异常。

    2.用户修改密码时,可能会因为输入的原密码错误导致修改失败,则应抛出PasswordNotMatchException异常。

    3.在执行修改密码时,如果返回的受影响行数与预期值不同,则应抛出UpdateException异常。

    4.创建com.cy.store.service.ex.UpdateException异常类,继承自ServiceException类。

    /** 更新数据的异常 */
    public class UpdateException extends ServiceException {
    	// Override Methods...
    }
    2.2 接口与抽象方法

    在IUserService中添加changePassword(Integer uid, String username, String oldPassword, String newPassword)抽象方法。

    /**
     * 修改密码
     * @param uid 当前登录的用户id
     * @param username 用户名
     * @param oldPassword 原密码
     * @param newPassword 新密码
     */
    public void changePassword(Integer uid, String username, String oldPassword, String newPassword);
    2.3 实现抽象方法

    1.在UserServiceImpl类中实现changePassword()抽象方法。

    public void changePassword(Integer uid, String username, String oldPassword, String newPassword) {
    	// 调用userMapper的findByUid()方法,根据参数uid查询用户数据
    	// 检查查询结果是否为null
    	// 是:抛出UserNotFoundException异常
    
    	// 检查查询结果中的isDelete是否为1
    	// 是:抛出UserNotFoundException异常
    
    	// 从查询结果中取出盐值
    	// 将参数oldPassword结合盐值加密,得到oldMd5Password
    	// 判断查询结果中的password与oldMd5Password是否不一致
    	// 是:抛出PasswordNotMatchException异常
    
    	// 将参数newPassword结合盐值加密,得到newMd5Password
    	// 创建当前时间对象
    	// 调用userMapper的updatePasswordByUid()更新密码,并获取返回值
    	// 判断以上返回的受影响行数是否不为1
    	// 是:抛了UpdateException异常
    }

    2.changePassword()方法的具体代码。

    String中的equals与contentEquals方法,都可以用来比较String对象内容是否相同。

    @Override
    public void changePassword(Integer uid, String username, String oldPassword, String newPassword) {
    	// 调用userMapper的findByUid()方法,根据参数uid查询用户数据
    	User result = userMapper.findByUid(uid);
    	// 检查查询结果是否为null
    	if (result == null) {
    		// 是:抛出UserNotFoundException异常
    		throw new UserNotFoundException("用户数据不存在");
    	}
    	
    	// 检查查询结果中的isDelete是否为1
    	if (result.getIsDelete().equals(1)) {
    		// 是:抛出UserNotFoundException异常
    		throw new UserNotFoundException("用户数据不存在");
    	}
    	
    	// 从查询结果中取出盐值
    	String salt = result.getSalt();
    	// 将参数oldPassword结合盐值加密,得到oldMd5Password
    	String oldMd5Password = getMd5Password(oldPassword, salt);
    	// 判断查询结果中的password与oldMd5Password是否不一致
    	if (!result.getPassword().contentEquals(oldMd5Password)) {
    		// 是:抛出PasswordNotMatchException异常
    		throw new PasswordNotMatchException("原密码错误");
    	}
    	
    	// 将参数newPassword结合盐值加密,得到newMd5Password
    	String newMd5Password = getMd5Password(newPassword, salt);
    	// 创建当前时间对象
    	Date now = new Date();
    	// 调用userMapper的updatePasswordByUid()更新密码,并获取返回值
    	Integer rows = userMapper.updatePasswordByUid(uid, newMd5Password, username, now);
    	// 判断以上返回的受影响行数是否不为1
    	if (rows != 1) {
    		// 是:抛出UpdateException异常
    		throw new UpdateException("更新用户数据时出现未知错误,请联系系统管理员");
    	}
    }

    3.在UserServiceTests中编写并执行单元测试。

    @Test
    public void changePassword() {
        try {
            Integer uid = 5;
            String username = "lower";
            String oldPassword = "123456";
            String newPassword = "888888";
            userService.changePassword(uid, username, oldPassword, newPassword);
            System.out.println("密码修改成功!");
        } catch (ServiceException e) {
            System.out.println("密码修改失败!" + e.getClass().getSimpleName());
            System.out.println(e.getMessage());
        }
    }

    3 用户-修改密码-控制器

    3.1 处理异常

    在用户修改密码的业务中抛出了新的UpdateException异常,需要在BaseController类中进行处理。

    @ExceptionHandler(ServiceException.class)
    public JsonResult handleException(Throwable e) {
    	JsonResult result = new JsonResult(e);
    	if (e instanceof UsernameDuplicateException) {
    		result.setState(4000);
    	} else if (e instanceof UserNotFoundException) {
    		result.setState(4001);
    	} else if (e instanceof PasswordNotMatchException) {
    		result.setState(4002);
    	} else if (e instanceof InsertException) {
    		result.setState(5000);
    	} else if (e instanceof UpdateException) {
    		result.setState(5001);
    	}
    	return result;
    }
    3.2 设计请求

    设计用户提交的请求,并设计响应的方式。

    请求路径:/users/change_password
    请求参数:String oldPassword, String newPassword, HttpSession session
    请求类型:POST
    响应结果:JsonResult

    3.3 处理请求

    1.在UserController类中添加处理请求的changePassword(String oldPassword, String newPassword, HttpSession session)方法。

    @RequestMapping("change_password")
    public JsonResult changePassword(String oldPassword, String newPassword, HttpSession session) {
    	// 调用session.getAttribute("")获取uid和username
    	// 调用业务对象执行修改密码
    	// 返回成功
    	
    	return null;
    }

    2.实现UserController控制器中的修改密码方法的代码。

    @RequestMapping("change_password")
    public JsonResult changePassword(String oldPassword, String newPassword, HttpSession session) {
    	// 调用session.getAttribute("")获取uid和username
    	Integer uid = getUidFromSession(session);
    	String username = getUsernameFromSession(session);
    	// 调用业务对象执行修改密码
    	iUserService.changePassword(uid, username, oldPassword, newPassword);
    	// 返回成功
    	return new JsonResult(OK);
    }

    3.启动项目先登录,再访问http://localhost:8080/users/change_password?oldPassword=xx&newPassword=xx进行测试。

    4 用户-修改密码-前端页面

    1.在password.html页面中body标签内部的最后,添加script标签用于编写JavaScript程序。

    
        $("#btn-change-password").click(function() {
            $.ajax({
                url: "/users/change_password",
                type: "POST",
                data: $("#form-change-password").serialize(),
                dataType: "json",
                success: function(json) {
                    if (json.state == 200) {
                        alert("修改成功!");
                    } else {
                        alert("修改失败!" + json.message);
                    }
                }
            });
    	});
    

    2.启动项目先登录,再访问http://localhost:8080/web/password.html页面并进行修改密码。

    问题:如果无法正常将数据传递给后台,重启动系统和IDEA开发工具,登陆后便可修改密码。

    3.问题:在操作前端页面时用户进入修改密码页面,长时间停留在当前页面未进行任何操作,将导致登录信息过期。此时点击修改按钮时,仍会向/users/change_password发送请求,会被拦截器重定向到登录页面。由于整个过程是由$.ajax()函数采用异步的方式处理的,所以重定向也是由异步任务完成的,在页面中没有任何表现就会出现“用户登录信息超时后点击按钮没有任何反应”的问题。

    解决方案:可以在password.html页面的$.ajax()中补充error属性的配置,该属性的值是一个回调函数。当服务器未正常响应状态码时,例如出现302、400、404、405、500等状态码时,将会调用该函数。

    error: function (xhr) {
        alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);
        location.href = "login.html";
    }

    个人资料

    1 用户-个人资料-持久层

    1.1 规划需要执行的SQL语句

    1.执行修改用户个人资料的SQL语句大致是:

    UPDATE t_user SET phone=?, email=?, gender=?, modified_user=?, modified_time=? WHERE uid=?

    2.在执行修改用户资料之前,当用户刚打开修改资料的页面时,就应把当前登录的用户信息显示到页面中。显示用户资料可以通过:

    SELECT * FROM t_user WHERE uid=?

    说明:

    1.该查询功能已经实现,无需再次开发;

    2.在执行修改用户资料之前,还应检查用户数据是否存在、是否标记为“已删除”,也可以通过以上查询来实现。

    1.2 接口与抽象方法

    在UserMapper接口中添加updateInfoByUid(User user)方法。

    /**
     * 根据uid更新用户资料
     * @param user 封装了用户id和新个人资料的对象
     * @return 受影响的行数
     */
    Integer updateInfoByUid(User user);
    1.3 配置SQL映射

    1.在UserMapper.xml中配置Integer updateInfoByUid(User user)抽象方法的映射。

    
    
    	UPDATE
    		t_user 
    	SET
    		phone = #{phone},
    		email = #{email},
    		gender = #{gender},
    		modified_user = #{modifiedUser},
    		modified_time = #{modifiedTime}
    	WHERE
    		uid = #{uid}
    

    2.在UserMapperTests中编写并执行单元测试。

    @Test
    public void updateInfoByUid() {
        User user = new User();
        user.setUid(20);
        user.setPhone("17858802222");
        user.setEmail("admin@cy.com");
        user.setGender(1);
        user.setModifiedUser("系统管理员");
        user.setModifiedTime(new Date());
        Integer rows = userMapper.updateInfoByUid(user);
        System.out.println("rows=" + rows);
    }

    2 用户-个人资料-业务层

    2.1 规划异常

    1.关于用户修改个人资料是由两个功能组成的。

    • 打开页面时显示当前登录的用户的信息;

    • 点击修改按钮时更新用户的信息。

    2.关于打开页面时显示当前登录的用户的信息,可能会因为用户数据不存在、用户被标记为“已删除”而无法正确的显示页面,则抛出UserNotFoundException异常。

    3.关于点击修改按钮时更新用户的信息,在执行修改资料之前仍需再次检查用户数据是否存在、用户是否被标记为“已删除”,则可能抛出UserNotFoundException异常。并且在执行修改资料过程中,还可能抛出UpdateException异常。

    2.2 接口与抽象方法

    在IUserService接口中添加两个抽象方法,分别对应以上两个功能。

    /**
     * 获取当前登录的用户的信息
     * @param uid 当前登录的用户的id
     * @return 当前登录的用户的信息
     */
    User getByUid(Integer uid);
    
    /**
     * 修改用户资料
     * @param uid 当前登录的用户的id
     * @param username 当前登录的用户名
     * @param user 用户的新的数据
     */
    void changeInfo(Integer uid, String username, User user);
    2.3 实现抽象方法

    1.在UserServiceImpl实现类中实现getByUid(Integer uid)和changeInfo(Integer uid, String username, User user)以上两个抽象方法。

    @Override
    public User getByUid(Integer uid) {
    	// 调用userMapper的findByUid()方法,根据参数uid查询用户数据
    	// 判断查询结果是否为null
    	// 是:抛出UserNotFoundException异常
    
    	// 判断查询结果中的isDelete是否为1
    	// 是:抛出UserNotFoundException异常
    
    	// 创建新的User对象
    	// 将以上查询结果中的username/phone/email/gender封装到新User对象中
    
    	// 返回新的User对象
    	return null;
    }
    
    @Override
    public void changeInfo(Integer uid, String username, User user) {
    	// 调用userMapper的findByUid()方法,根据参数uid查询用户数据
    	// 判断查询结果是否为null
    	// 是:抛出UserNotFoundException异常
    
    	// 判断查询结果中的isDelete是否为1
    	// 是:抛出UserNotFoundException异常
    
    	// 向参数user中补全数据:uid
    	// 向参数user中补全数据:modifiedUser(username)
    	// 向参数user中补全数据:modifiedTime(new Date())
    	// 调用userMapper的updateInfoByUid(User user)方法执行修改,并获取返回值
    	// 判断以上返回的受影响行数是否不为1
    	// 是:抛出UpdateException异常
    	
    }

    2.getByUid(Integer uid)和changeInfo(Integer uid, String username, User user)方法的具体代码实现。

    @Override
    public User getByUid(Integer uid) {
    	// 调用userMapper的findByUid()方法,根据参数uid查询用户数据
    	User result = userMapper.findByUid(uid);
    	// 判断查询结果是否为null
    	if (result == null) {
    		// 是:抛出UserNotFoundException异常
    		throw new UserNotFoundException("用户数据不存在");
    	}
     
    	// 判断查询结果中的isDelete是否为1
    	if (result.getIsDelete().equals(1)) {
    		// 是:抛出UserNotFoundException异常
    		throw new UserNotFoundException("用户数据不存在");
    	}
    
    	// 创建新的User对象
    	User user = new User();
    	// 将以上查询结果中的username/phone/email/gender封装到新User对象中
    	user.setUsername(result.getUsername());
    	user.setPhone(result.getPhone());
    	user.setEmail(result.getEmail());
    	user.setGender(result.getGender());
    	
    	// 返回新的User对象
    	return user;
    }
    
    @Override
    public void changeInfo(Integer uid, String username, User user) {
    	// 调用userMapper的findByUid()方法,根据参数uid查询用户数据
    	User result = userMapper.findByUid(uid);
    	// 判断查询结果是否为null
    	if (result == null) {
    		// 是:抛出UserNotFoundException异常
    		throw new UserNotFoundException("用户数据不存在");
    	}
    
    	// 判断查询结果中的isDelete是否为1
    	if (result.getIsDelete().equals(1)) {
    		// 是:抛出UserNotFoundException异常
    		throw new UserNotFoundException("用户数据不存在");
    	}
    
    	// 向参数user中补全数据:uid
    	user.setUid(uid);
    	// 向参数user中补全数据:modifiedUser(username)
    	user.setModifiedUser(username);
    	// 向参数user中补全数据:modifiedTime(new Date())
    	user.setModifiedTime(new Date());
    	// 调用userMapper的updateInfoByUid(User user)方法执行修改,并获取返回值
    	Integer rows = userMapper.updateInfoByUid(user);
    	// 判断以上返回的受影响行数是否不为1
    	if (rows != 1) {
    		// 是:抛出UpdateException异常
    		throw new UpdateException("更新用户数据时出现未知错误,请联系系统管理员");
    	}
    }

    3.在UserServiceTests类中进行单元测试。

    @Test
    public void getByUid() {
        try {
            Integer uid = 20;
            User user = iUserService.getByUid(uid);
            System.out.println(user);
        } catch (ServiceException e) {
            System.out.println(e.getClass().getSimpleName());
            System.out.println(e.getMessage());
        }
    }
    
    @Test
    public void changeInfo() {
        try {
            Integer uid = 20;
            String username = "数据管理员";
            User user = new User();
            user.setPhone("15512328888");
            user.setEmail("admin03@cy.cn");
            user.setGender(2);
            iUserService.changeInfo(uid, username, user);
            System.out.println("OK.");
        } catch (ServiceException e) {
            System.out.println(e.getClass().getSimpleName());
            System.out.println(e.getMessage());
        }
    }

    3 用户-个人资料-控制器

    3.1 处理异常

    说明:无需再次开发。

    3.2 设计请求

    1.设计用户提交显示当前登录的用户信息的请求,并设计响应的方式。

    请求路径:/users/get_by_uid
    请求参数:HttpSession session
    请求类型:GET
    响应结果:JsonResult

    2.设计用户提交执行修改用户信息的请求,并设计响应的方式。

    请求路径:/users/change_info
    请求参数:User user, HttpSession session
    请求类型:POST
    响应结果:JsonResult

    3.3 处理请求

    1.处理获取用户信息请求

    1.在UserController类中添加处理请求的getByUid()方法,并导入org.springframework.web.bind.annotation.GetMapping包。

    @GetMapping("get_by_uid")
    public JsonResult getByUid(HttpSession session) {
    	// 从HttpSession对象中获取uid
    	// 调用业务对象执行获取数据
    	// 响应成功和数据
    	return null;
    }

    2.getByUid(HttpSession session)方法中具体代码实现为。

    @GetMapping("get_by_uid")
    public JsonResult getByUid(HttpSession session) {
        // 从HttpSession对象中获取uid
        Integer uid = getUidFromSession(session);
        // 调用业务对象执行获取数据
        User data = userService.getByUid(uid);
        // 响应成功和数据
        return new JsonResult(OK, data);
    }

    3.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/users/get_by_uid请求进行测试。

    2.处理修改用户个人信息请求

    1.在UserController类中添加处理请求的changeInfo(User user, HttpSession session)方法。

    @RequestMapping("change_info")
    public JsonResult changeInfo(User user, HttpSession session) {
    	// 从HttpSession对象中获取uid和username
    	// 调用业务对象执行修改用户资料
    	// 响应成功
    	return null;
    }

    2.changeInfo(User user, HttpSession session)方法中具体代码实现为。

    @RequestMapping("change_info")
    public JsonResult changeInfo(User user, HttpSession session) {
    	// 从HttpSession对象中获取uid和username
    	Integer uid = getUidFromSession(session);
    	String username = getUsernameFromSession(session);
    	// 调用业务对象执行修改用户资料
    	userService.changeInfo(uid, username, user);
    	// 响应成功
    	return new JsonResult(OK);
    }

    3.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/users/change_info?phone=17858800000&email=admin07@cy.com&gender=1进行测试。

    4 用户-个人资料-前端页面

    1.在userdata.html页面中body标签内部的最后,添加script标签用于编写JavaScript程序。

    
        $(document).ready(function() {
            $.ajax({
                url: "/users/get_by_uid",
                type: "GET",
                dataType: "json",
                success: function(json) {
                    if (json.state == 200) {
                        console.log("username=" + json.data.username);
                        console.log("phone=" + json.data.phone);
                        console.log("email=" + json.data.email);
                        console.log("gender=" + json.data.gender);
    
                        $("#username").val(json.data.username);
                        $("#phone").val(json.data.phone);
                        $("#email").val(json.data.email);
    
                        let radio = json.data.gender == 0 ? $("#gender-female") : $("#gender-male");
                        radio.prop("checked", "checked");
                    } else {
                        alert("获取用户信息失败!" + json.message);
                    }
                }
            });
    	});
    
        $("#btn-change-info").click(function() {
            $.ajax({
                url: "/users/change_info",
                type: "POST",
                data: $("#form-change-info").serialize(),
                dataType: "json",
                success: function(json) {
                    if (json.state == 200) {
                        alert("修改成功!");
                        location.href = "login.html";
                    } else {
                        alert("修改失败!" + json.message);
                    }
                },
                error: function(xhr) {
                    alert("您的登录信息已经过期,请重新登录!HTTP响应码:" + xhr.status);
                    location.href = "login.html";
                }
            });
        });
    

    2.完成后启动项目,打开浏览器先登录,再访问http://localhost:8080/web/userdata.html页面并进行用户个人资料的修改测试。

    本文内容来源于互联网,如有侵权请联系删除。
    作者最新文章
    编程开发
    相关文章 更多
    using namespace 使用中遇到的问题怎么解决
    using namespace 使用中遇到的问题怎么解决

    命名空间的基本概念与常见引入问题在C++等编程语言中,命名空间(namespace)是一种将代码标识符(如变量、函数、类名)封装在特定名称下的机制,其主要目的是避免命名冲突,尤其是在大型项目或使用多个第三方库时。使用“using namespace”指令可以将指定命名空间中的所有名称引入当前作用域,

    c语言函数递归 实操经验总结:这些技巧很实用
    c语言函数递归 实操经验总结:这些技巧很实用

    理解递归的基本原理在C语言中,递归是一种函数调用自身的编程技术。要掌握它,首先需要理解其核心思想:将一个复杂的大问题,分解为一个或几个与原问题相似但规模更小的子问题,直到子问题足够简单,可以直接求解。这个过程通常包含两个关键部分:递归出口和递归体。递归出口定义了问题何时不再继续分解,即最简单、可直接

    c语言函数递归 怎么选?常见方案对比分析
    c语言函数递归 怎么选?常见方案对比分析

    递归函数的基本概念与适用场景在C语言编程中,递归是一种函数调用自身的编程技巧。它并非适用于所有问题,但在处理某些具有自相似结构的问题时,能提供极其清晰和优雅的解决方案。递归的核心思想是将一个大规模问题分解为一个或多个同类型但规模更小的子问题,直到子问题简单到可以直接求解。典型的适用场景包括树形结构的

    Objective-C 内存管理入门:从 alloc 到 dealloc 的生命周期详解
    Objective-C 内存管理入门:从 alloc 到 dealloc 的生命周期详解

    理解内存管理的基石在Objective-C的编程世界中,内存管理是开发者必须掌握的核心技能之一。它直接关系到应用的性能、稳定性与资源利用效率。与一些采用自动垃圾回收机制的语言不同,Objective-C在很长一段时间里,依赖一套基于引用计数的、需要开发者部分介入的管理规则。这套规则的核心思想是明确的

    如何正确使用 dealloc 以避免 iOS 应用中的内存泄漏
    如何正确使用 dealloc 以避免 iOS 应用中的内存泄漏

    理解 dealloc 的角色与时机在 iOS 应用开发中,内存管理是保障应用性能与稳定性的基石。dealloc 方法是 Objective-C 中对象生命周期结束时的关键回调,它标志着对象即将被系统回收内存。正确理解其触发时机至关重要:当一个对象的引用计数降为零时,运行时系统会自动调用该对象的 de

    深入理解 Objective-C 中的 dealloc 方法:内存管理核心机制
    深入理解 Objective-C 中的 dealloc 方法:内存管理核心机制

    内存管理的基石在Objective-C的世界里,内存管理是开发者必须掌握的核心技能之一。作为一门在手动引用计数(MRC)时代诞生的语言,Objective-C要求程序员对对象的生命周期有清晰的认识。dealloc方法正是这一生命周期中至关重要的终点站。它是一个实例方法,当对象的引用计数降为零时,系统

    理解 native2ascii:Java 国际化开发中的字符编码工具
    理解 native2ascii:Java 国际化开发中的字符编码工具

    native2ascii 工具的基本定位在Ja va应用程序的国际化与本地化开发过程中,处理非拉丁字符集是一个常见且关键的环节。Ja va内部使用Unicode字符集来统一表示全球各种语言的文字,但其属性文件(.properties)在历史上要求使用ASCII编码,或者更准确地说,要求非ASCII字

    如何使用 native2ascii 转换中文字符为 Unicode 转义序列
    如何使用 native2ascii 转换中文字符为 Unicode 转义序列

    理解 native2ascii 工具的基本用途在软件开发,特别是涉及国际化处理的场景中,开发者常常需要处理不同编码的文本资源。native2ascii 是 Ja va 开发工具包(JDK)中提供的一个命令行实用程序,其主要功能是将包含本地字符编码(非ASCII字符)的文件,转换为包含 Unicode

    Java native2ascii 命令详解:解决属性文件乱码问题
    Java native2ascii 命令详解:解决属性文件乱码问题

    native2ascii 命令的由来与作用在Ja va开发中,处理国际化资源文件是一个常见需求。资源文件通常以.properties格式存储,用于支持多语言界面。然而,Ja va属性文件默认采用ISO-8859-1字符集编码,这导致了一个直接的问题:当文件中包含非拉丁字符(如中文、日文、韩文等)时,

    一个 memwatch 实战案例:定位野指针问题
    一个 memwatch 实战案例:定位野指针问题

    内存监控工具的价值与挑战在软件开发,尤其是使用C/C++这类手动管理内存的语言时,内存错误是程序员最常遭遇的难题之一。其中,野指针问题因其隐蔽性和破坏性,往往成为最难定位的“幽灵”缺陷。它可能潜伏在代码中,在特定条件下才被触发,导致程序崩溃、数据损坏或难以预测的行为。传统的调试手段,如打印日志或使用

    查看更多
    精品专题 更多
    装机必备
    装机必备

    正软商城装机必备专区,精选办公、浏览器、安全防护、影音播放、压缩解压、设计创作和系统工具等电脑常用正版软件,帮助用户快速完成新电脑软件配置。

    Windows
    Windows

    正软商城Windows软件专区,汇集适用于Windows电脑的办公、设计、安全防护、影音播放、开发工具和系统优化软件,提供软件介绍、系统要求、正版授权及购买下载服务。

    macOS软件
    macOS软件

    正软商城macOS软件专区,精选适用于Mac电脑的办公、设计、影音、效率、开发和系统工具,提供软件功能介绍、macOS兼容版本、正版授权及购买下载服务。

    Mac软件 更多
    灵活计算器
    灵活计算器
    macOS/iOS/Android

    灵活计算器是一款笔记式算数应用,支持实时计算、动态关联和云端同步功能。记录、整理和输出之间的过渡会更自然,适合长期写作、做笔记或持续沉淀个人内容。

    赤友清理大师
    赤友清理大师
    macOS

    赤友清理大师是一款为 Mac 设计的智能清理优化工具,可精准扫描垃圾、大文件、重复文件等,释放磁盘空间。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    极度公式
    极度公式
    Windows/macOS/Linux

    极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    WINDOWS 更多
    Windows 10
    Windows 10
    Windows

    Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。

    极度公式
    极度公式
    Windows/macOS/Linux

    极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。

    密码键盘
    密码键盘
    Windows/macOS/iOS/Android

    密码键盘是一款兼具安全性与便捷性的高效密码管理器。日常使用里的持续防护和信息管理会更突出,适合把安全控制放进长期使用流程中的场景。