(补)HttpServletRequest的应用 .

本文介绍如何处理HTTP请求中的实体内容,包括使用getInputStream和getReader方法读取文件上传的数据,并深入探讨了请求参数中中文乱码的问题及其解决方案。
 一.获取请求消息中的实体内容getInputStream和getReader方法

1.getInputStream方法是字节的输入流对象,返回的是一个代表实体内容的实体对象。类型为javax.servlet.ServletInputStream

2.getReader方法是返回的是一个BufferedReader的对象,返回的BufferedReader对象将实体内容中的字节数据按照请求消息中指定的字符集编码转换成文本字符串

       注:在调用getRader方法之前,可以调用setCharacterEncoding方法指定其返回的BufferedReader对象所使用的字符集编码。

3.实例是文件上传-----------读取实体内容的举例

第一步:在html文档中写一个表单

<form method="post" action="testInput" name="form1" enctype="multipart/form-data">

         请输入第一个参数:<input type="text" name="param1"/><br/>

   <!-- 上传文件 -->

         <input type="file" name="f1"/>

       //提交

          <input type="submit" name="ok" value="submit"/>

    </form> 

         注:enctype="multipart/form-data"是来确保匿名上载文件的正确编码.

第二步:

第一种:

              // 获取字符的输入流对象

       BufferedReader br = request.getReader();

       FileWriter fw = new FileWriter(“d:/ouc.txt”);

       // 把读取到的字符放到数组里来保存

       char[] arr = new char[1024];

       // 并读取出来显示

       while (br.read(arr) != -1) {

           读取的字符数组从控制台输出或输入到一个指定的文件中

           System.out.println(new String(arr, 0, arr.length));

           //fw.write(arr);

       }

       fw.close();

 

       第二种:

       // 获取字符的输入流对象

       BufferedReader br = request.getReader();

       //通过上下文对象获取它的对象

       ServletContext context = this.getServletContext();

       //获取指定文件的真实路径

       String filename = context.getRealPath("/out.txt");

       //输出流把读取到的内容写到文件中去

       FileWriter fw = new FileWriter(filename);

 

      

       // 把读取到的字符放到数组里来保存

       char[] arr = new char[1024];

       // 并读取出来显示

       while (br.read(arr) != -1) {

           读取的字符数组从控制台输出或输入到一个指定的文件中

           System.out.println(new String(arr, 0, arr.length));

           //fw.write(arr);

       }

       fw.close();

             

二.请求参数中中文的读取问题

       学习的原因:解决乱码的原因

1、  了解中文字符的URL编码

对Java中的某个字符串进行URL编码,其实是在对它的某种字符集编码(非Unicode码)数据进行URL编码,而Java中的字符串是以Unicode字符集编码存在的,所以,在对Java中的字符串进行URL编码时,必须指定是对这个字符串的哪种非Unicode的字符集编码进行URL编码。

                     浏览器对请求参数中的字符的某种字符进行的编码是URL编码

2、浏览器解析的步骤:

                       中(从文本框中输入的) ------utf-8的字符集是E4B8AD -----à  服务器会对它进行URL编码(%E4%B8%AD)----à  在解码后成为字节数组,按照某种字符编码进行解码, 编译之后的字符发送给Web服务器

3、  出现乱码的解决办法:

getParameter方法的中文问题

        (1)getParameter等方法在读取的参数信息时,需要进行URL解码。

(2)对于HTTP请求消息的请求行中的URL地址后的参数,getParameter等方法进行URL解码时所采用的字符集编码在Servlet规范中没有明确规定Tomcat中的ServletRequest对象的getParameter等方法默认采用ISO8859-1字符集编码进行URL解码,因此无法返回正确的中文参数信息 。

(3)对于POST方式下的“application/x-www-form-urlencoded”编码格式的实体内容,getParameter等方法以ServletRequest对象的getCharacterEncoding()方法返回的字符   集编码对其进行URL解码。

(4)getCharacterEncoding()方法的返回值通常为null,对于这种情况,ServletRequest对象的getParameter等方法将使用默认的ISO8859-1字符集编码对实体内容中的参数进行URL解码,因此也将无法返回正确的中文参数信息。

(5)ServletRequest接口中定义了一个setCharacterEncoding方法来设置请求消息中的实体内容的字符集编码名称,getParameter方法将以该方法设置的字符集编码对实体     内容进行URL解码。

(6)setCharauanycterEncoding方法设置的是请求消息中的实体内容的字符集编码名称,它只影响getParameter方法对POST方式下的“application/x-www-form-urlencoded”编码格式的实体内容进行URL解码的结果,而不能影响getParameter方法对HTTP请求消息的请求行中的URL地址后的参数进行URL解码的结果。 

 

注:Web服务器从请求消息中把每一个参数名和参数值分离出来的每一个参数名和参数值也会针对某种字符集编码进行URL解码     

字符的编码方式是对实体内容的设置

4、  乱码出现的原因有几种情况

(1)       是在html文档中有设置字符编码的,

(2)       是在request中设置编码字符集

request.setCharacterEncoding("utf-8");

(3)是在request中设置编码字符集,

                              response.setContentType("text/html;charset=utf-8");

(4)在提交方式不同的时候,比如是用get方法提交的话,在控制台窗口就可能输出乱码,可以再service中修改为:

                           <Connector executor="tomcatThreadPool"

                           port="8080" protocol="HTTP/1.1"

                           connectionTimeout="20000"

                           redirectPort="8443" useBodyEncodingForURL="true"/>

集,

                              response.setContentType("text/html;charset=utf-8");

(4)在提交方式不同的时候,比如是用get方法提交的话,在控制台窗口就可能输出乱码,可以再service中修改为:

                           <Connector executor="tomcatThreadPool"

                           port="8080" protocol="HTTP/1.1"

                           connectionTimeout="20000"

                           redirectPort="8443" useBodyEncodingForURL="true"/>

package com.vilicode.Utils; import java.nio.charset.StandardCharsets; import java.security.Key; import java.security.SecureRandom; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.SecretKeyFactory; import javax.crypto.spec.DESKeySpec; import java.util.Base64; public class MyCipher { public MyCipher() { } private Key getKeyt(String str) { try { // 使用 DES 算法,密钥长度必须为 56 位(7 字节) byte[] keyBytes = new byte[8]; byte[] strBytes = str.getBytes(StandardCharsets.UTF_8); // 将输入字符串的字节复制到密钥数组中 // 如果字符串长度不足 8 字节,则剩余位置 0 for (int i = 0; i < Math.min(strBytes.length, 8); i++) { keyBytes[i] = strBytes[i]; } // DES 密钥需要满足奇偶校验位(每字节的第 8 位) // 这里简单处理,实际生产环境建议使用更安全的方式 for (int i = 0; i < 8; i++) { keyBytes[i] = (byte) (keyBytes[i] & 0xfe); // 清除最后一位 int parity = 0; for (int j = 0; j < 7; j++) { parity ^= (keyBytes[i] >> j) & 1; } keyBytes[i] |= parity; // 设置奇偶校验位 } // 使用 DESKeySpec 生成密钥 DESKeySpec desKeySpec = new DESKeySpec(keyBytes); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); return keyFactory.generateSecret(desKeySpec); } catch (Exception e) { e.printStackTrace(); return null; } } private byte[] getEncrypt(byte[] plaintexts, String str) { Key key = this.getKeyt(str); byte[] ciphertexts = null; Cipher cipher; try { cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key); ciphertexts = cipher.doFinal(plaintexts); } catch (Exception var10) { var10.printStackTrace(); } finally { cipher = null; } return ciphertexts; } public String encrypt(String plaintext, String str) { String ciphertext = ""; try { byte[] plaintexts = plaintext.getBytes(StandardCharsets.UTF_8); // 调用调整后的 getKeyt 方法生成密钥,保证密钥生成逻辑统一 Key key = getKeyt(str); if (key == null) { // 密钥生成失败时的处理,可根据实际需求抛出异常或返回特定标识 return ciphertext; } Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.ENCRYPT_MODE, key); byte[] ciphers = cipher.doFinal(plaintexts); if (ciphers != null) { ciphertext = Base64.getEncoder().encodeToString(ciphers); } } catch (Exception var7) { var7.printStackTrace(); } return ciphertext; } private byte[] decrypt(byte[] ciphertexts, String str) { Key key = this.getKeyt(str); byte[] plaintexts = null; Cipher cipher; try { cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, key); plaintexts = cipher.doFinal(ciphertexts); } catch (Exception var10) { System.out.println(var10.getMessage()); } finally { cipher = null; } return plaintexts; } public String decrypt(String ciphertext, String str) { String plaintext = ""; try { byte[] bytes = Base64.getDecoder().decode(ciphertext); Key key = getKeyt(str); if (key == null) { return plaintext; } Cipher cipher = Cipher.getInstance("DES"); cipher.init(Cipher.DECRYPT_MODE, key); byte[] ciphers = cipher.doFinal(bytes); if (ciphers != null) { plaintext = new String(ciphers, StandardCharsets.UTF_8); } } catch (Exception var7) { var7.printStackTrace(); } return plaintext; } } package com.vilicode.controller; import com.vilicode.Utils.MyCipher; import com.vilicode.bean.Page; import com.vilicode.bean.User; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import com.vilicode.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @Controller public class UserController { private MyCipher myCipher = new MyCipher(); @Autowired private UserService userService; @RequestMapping("/login") public String login(User tempUser, HttpServletRequest request, HttpSession session) { // 获取用户输入的明文密码 String plainPassword = tempUser.getUpwd(); // 根据用户名查询数据库用户信息 User user = userService.login(tempUser.getUname()); if (user == null) { request.setAttribute("failMsg", "用户名不存在!"); return "user_login"; } // 加密用户输入的明文密码(使用 MyCipher 工具类) String encryptedInputPassword = myCipher.encrypt(plainPassword, "!"); // 获取数据库中存储的加密密码 String storedEncryptedPassword = user.getUpwd(); // 对比加密后的密码 if (encryptedInputPassword.equals(storedEncryptedPassword)) { session.setAttribute("user", user); request.setAttribute("msg", "登录成功!"); return "redirect:/index.action"; } else { request.setAttribute("failMsg", "密码错误!"); return "user_login"; } } @RequestMapping("/register") public String register(User user, HttpServletRequest request) { String path=""; user.setUrole(1); user.setUmark("普通用户"); if(userService.register(user)) { path="redirect:user_login.jsp"; }else{ request.setAttribute("msg","用户名重复!"); path="user_register"; } return path; } @RequestMapping("/admin/user_add") public String AddUser(User user, HttpServletRequest request) { user.setUrole(1); user.setUmark("普通用户"); if(userService.register(user)) { return "redirect:user_list.action?pageNumber=1"; }else{ request.setAttribute("msg","用户名重复!"); return "admin/user_add"; } } @RequestMapping("/logout") public String logout(HttpServletRequest request) { request.getSession().removeAttribute("user"); return "redirect:index.action"; } @RequestMapping("/admin/logout") public String adminLogout(HttpServletRequest request) { request.getSession().removeAttribute("user"); return "redirect:index.action"; } @RequestMapping("/change_phone_and_address") public String updateUphoneAndUaddress(int uid,String uphone,String uaddress,HttpServletRequest request) { boolean result=userService.UpdatePhoneAndAddress(uid,uphone,uaddress); if(result) { request.setAttribute("msg","修改成功!"); User u=(User)request.getSession().getAttribute("user"); u.setUaddress(uaddress); u.setUphone(uphone); request.getSession().removeAttribute("user"); request.getSession().setAttribute("user",u); return "user_center"; } else { request.setAttribute("failMsg","修改密码时出现错误,请确认原密码是否正确或联系管理员!"); return "user_center"; } } @RequestMapping("/change_password") public String updatePassword(int uid,String oldupwd,String upwd,HttpServletRequest request) { boolean result=userService.UpdatePassword(uid,upwd,oldupwd); if(result) { request.setAttribute("msg","修改成功!"); MyCipher myCipher=new MyCipher(); User u=(User)request.getSession().getAttribute("user"); u.setUpwd(myCipher.encrypt(upwd,"!")); request.getSession().removeAttribute("user"); request.getSession().setAttribute("user",u); return "user_center"; } else { request.setAttribute("failMsg","修改密码时出现错误,请确认原密码是否正确或联系管理员!"); return "user_center"; } } @RequestMapping("admin/change_password") public String updatePassword(int uid,String upwd,HttpServletRequest request) { boolean result=userService.UpdatePassword(uid,upwd); if(result) { MyCipher myCipher=new MyCipher(); request.setAttribute("msg","修改成功!"); User u=(User)request.getSession().getAttribute("user"); u.setUpwd(myCipher.encrypt(upwd,"!")); request.getSession().removeAttribute("user"); request.getSession().setAttribute("user",u); return "redirect:user_list.action?pageNumber=1"; } else { request.setAttribute("failMsg","修改失败"); return "redirect:user_list.action?pageNumber=1"; } } @RequestMapping("admin/user_list") public String ShowUserList(int pageNumber,HttpServletRequest request) { if(pageNumber<=0) pageNumber=1; Page p = userService.queryUser(pageNumber); if(p.getTotalPage()==0) { p.setTotalPage(1); p.setPageNumber(1); } else { if(pageNumber>=p.getTotalPage()+1) { p = userService.queryUser(p.getTotalPage()); } } request.setAttribute("p", p); return "admin/user_list"; } @RequestMapping("admin/user_delete") public String DeleteUser(int uid) { boolean result= userService.deleteUser(uid); return "redirect:user_list.action?pageNumber=1"; } @RequestMapping("/admin/user_edit_show") public String ChangeUser(int uid,HttpServletRequest request) { User user=userService.queryUserByUid(uid); if(user==null) return "redirect:user_list.action?pageNumber=1"; else { request.setAttribute("u",user); return "admin/user_edit"; } } @RequestMapping("/admin/user_update") public String updateUser(int uid,String uphone,String uaddress,HttpServletRequest request) { boolean result=userService.UpdatePhoneAndAddress(uid,uphone,uaddress); if(result) { User user=(User)request.getSession().getAttribute("user"); if(user.getUid()==uid) { user.setUaddress(uaddress); user.setUphone(uphone); request.getSession().removeAttribute("user"); request.getSession().setAttribute("user",user); } } return "redirect:user_list.action?pageNumber=1"; } } 根据这两个代码使其能够密码加密解密成功
06-19
// 定义包路径 package com.wuyunbin.jmb2c.service.impl; // 导入相关类 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.wuyunbin.jmb2c.dto.MemberLoginDTO; import com.wuyunbin.jmb2c.dto.MemberUpdatePasswordDTO; import com.wuyunbin.jmb2c.entity.Member; import com.wuyunbin.jmb2c.exceptions.BusinessException; import com.wuyunbin.jmb2c.mapper.MemberMapper; import com.wuyunbin.jmb2c.service.MemberService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.wuyunbin.jmb2c.utils.JwtUtil; import io.jsonwebtoken.Claims; import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; import java.util.HashMap; /** * 会员服务实现类 * 实现会员相关的业务逻辑,包括登录、获取用户信息、更新密码等功能 * * @author wuyunbin * @since 2025-07-02 */ // 启用日志功能 @Slf4j // 标记为服务类 @Service public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService { // 注入RestTemplate,用于发送HTTP请求 @Resource private RestTemplate restTemplate; // 注入HttpServletRequest,用于获取请求中的信息(如token) @Resource private HttpServletRequest request; // 注入JWT工具类,用于处理token @Resource private JwtUtil jwtUtil; /** * 用户登录实现 * 支持账号密码登录,验证用户身份并生成JWT令牌 * * @param memberLoginDTO 登录信息数据传输对象 * @return 生成的JWT令牌 * @throws BusinessException 当账号不存在或密码错误时抛出 */ @Override public String login(MemberLoginDTO memberLoginDTO) { Member member=null; // 账号密码登录 if(memberLoginDTO.getMobile()!=null){ // 创建查询条件 LambdaQueryWrapper<Member> wrapper=new LambdaQueryWrapper<>(); // 根据手机号查询用户 wrapper.eq(Member::getMobile,memberLoginDTO.getMobile()); // 获取用户信息 member = this.getOne(wrapper); // 检查用户是否存在 if(member==null){ log.info("账号不存在"); throw new BusinessException("账号不存在或密码错误"); } // 验证密码是否正确 if(!member.getPassword().equals(memberLoginDTO.getPassword())){ log.info("密码错误"); throw new BusinessException("账号不存在或密码错误"); } }else{ // todo 0702 微信登录 } // 签发token HashMap<String,Object> map=new HashMap<>(); // 将用户ID存入token map.put("id",member.getUserId()); // 生成JWT令牌 String token = jwtUtil.generateToken(map); return token; } /** * 获取当前登录用户信息 * 从请求头中获取token,解析出用户ID,然后查询用户信息 * * @return 当前登录用户的信息 */ @Override public Member info() { // 从请求头获取token String token = request.getHeader("token"); log.info("token:{}",token); // 解析token,获取用户ID Claims claims = jwtUtil.parseToken(token); Integer id = claims.get("id", Integer.class); // 根据用户ID查询用户信息 Member member = this.getById(id); return member; } /** * 更新用户密码 * 根据用户ID更新密码信息 * * @param memberUpdatePasswordDTO 密码更新信息数据传输对象 */ @Override public void updatePassword(MemberUpdatePasswordDTO memberUpdatePasswordDTO) { // 创建Member对象 Member member=new Member(); // 设置用户ID member.setUserId(memberUpdatePasswordDTO.getUserId()); // 设置新密码 member.setPassword(memberUpdatePasswordDTO.getPassword()); // 更新用户信息 this.updateById(member); } } 帮我上 // todo 0702 微信登录中的代码,并添加详尽的注释
07-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值