实习时遇到的后端问题,学习一下

本文深入探讨了RESTful规范及其实现,包括使用@PathVariable获取参数、RestTemplate请求资源及常见错误处理。同时,详细介绍了SpringBoot下WebSocket的配置与应用,实现客户端与服务端的长连接交互,以及图片上传功能的两种实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

学多少更多少emmmmm

今天学到一个后端开发resetful规范,附大佬链接:
https://blog.csdn.net/LeiXiaoTao_Java/article/details/83621357
在resetful风格中会用到占位符{x}获取参数,用注释@PathVariable注入参数


之前用过RestTemplate去请求资源忘了记下来,现在补一下,先上一段代码

		//请求体数据
        MultiValueMap<String,String> map=new LinkedMultiValueMap<>();
        map.add("mobile",mobile);
		RestTemplate restTemplate=new RestTemplate();
		//请求头设置
        HttpHeaders header = new HttpHeaders();
        header.add("Accept", "application/json");
        header.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //构造请求
        HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity<>(map, header);
        ResponseEntity<String> responseEntity=restTemplate.postForEntity(url,httpEntity,String.class);

400 / Bad Request 数据格式出现问题


spring boot 下的WebSocket:
一般服务端与客户端交互通过http协议进行交互,但是只能实现客户端向服务端请求资源,那么当我需要服务端主动向客户端发送消息就要用到websocket去实现,websocket其实就是封装好的一个socket工具,通过配置使用,实现客户端和服务端的长连接,上代码

//websocketconfig
@Configuration
public class WebSocketConfig {
    @Bean
    public ServerEndpointExporter serverEndpointExporter(){
        return new ServerEndpointExporter();
    }
}

//websocketserver
//为什么要分多一个类去实现具体方法,因为这里的方法通过配置定义的都是当websocket打开,收到消息
//,错误时的处理方式,另外定义一个类进行操作的好处在于你可以通过它去实现自定义的功能,即可以调
//用里面的方法在不同地方实现自定义的功能,这里只是定义了触发websocket基本操作
@ServerEndpoint("/websocket/{token}")
@Component
public class WebSocketServer {
    private static WebSocketService webSocketService;
    @Autowired
    public void setWebSocketService(WebSocketService webSocketService){
        WebSocketServer.webSocketService=webSocketService;
    }
    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token){
        webSocketService.onOpen(session,token);
    }
    @OnMessage
    public void onMessage(Session session,String message){
        webSocketService.onMessage(session,message);
    }
    @OnError
    public void onError(Session session,Throwable error){
        webSocketService.onError(session,error);
    }
}

//websocketservice
@Service
public class WebSocketService {
    // Session id -> id
    private ConcurrentMap<String,String> idMap=new ConcurrentHashMap<>();
    // id -> List<Session>
    private ConcurrentMap<String,List<Session>> connectionMap=new ConcurrentHashMap<>();
    
    public void onOpen(Session session,String token){
        System.out.println("onOpen:"+token);
        String Id = IotUtil.getInfoByToken(token);
        Admin admin=adminRepository.findById(Long.valueOf(Id));
        idMap.put(session.getId(),Id);
        if(connectionMap.containsKey(Id)){
            connectionMap.get(Id).add(session);
        }else{
            List<Session> list=new ArrayList<>();
            list.add(session);
            connectionMap.put(Id,list);
        }
    }


    public void onMessage(Session session,String message){
        System.out.println(session.getId()+":"+message);
        if(idMap.containsKey(session)){
            return;
        }
    }

    public void onError(Session session,Throwable error){
        System.out.println("onError:"+session.getId());
        closeSession(session);
    }

    private void closeSession(Session session){
        if(idMap.containsKey(session.getId())){
            String Id=idMap.get(session.getId());
            List<Session> sessionList=connectionMap.get(Id);
            sessionList.remove(session);
        }
        try {
            session.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void sendMessge(String adminId,String message){
        if(!connectionMap.containsKey(adminId)){
            return;
        }
        List<Session> list=connectionMap.get(adminId);
        for(int i=0;i<list.size();i++){
            try {
                list.get(i).getBasicRemote().sendText(JSON.toJSONString(message));
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    public void sendMessage(List<String> adminIdList,String message){
        for(String id:adminIdList){
            sendMessge(id,message);
        }
    }
}

实现上传照片功能,后台能直接接受文件类型,使用MultipartFile类型接受文件,实现照片上传。另一种就是接受base64编码的图片,后台解析生成图片下载。

    @ApiOperation("文件形式上传图片"
    public RspVo uploadPicture(MultipartFile image) {
        if (image == null) {
            return this.ajaxError();
        }
        File uploadImageDir = new File(UPLOAD_FOLDER);
        if (!uploadImageDir.exists()) {
            boolean success = uploadImageDir.mkdir();
            if (success) {
                System.out.println("文件夹创建成功");
            } else {
                System.out.println("文件夹创建失败");
            }
        }
        String path=UPLOAD_FOLDER + image.getOriginalFilename();
        File saveToServerImage = new File(path);
        try {
            image.transferTo(saveToServerImage);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return this.ajaxSuccess(path);
    }

    @ApiOperation("base64编码上传图片")
    public RspVo uploadPictureByBase64(@RequestBody  String imageBase64) {
        if (imageBase64 == null) {
            return this.ajaxError();
        }
        File uploadImageDir = new File(UPLOAD_FOLDER);
        if (!uploadImageDir.exists()) {
            boolean success = uploadImageDir.mkdir();
            if (success) {
                System.out.println("文件夹创建成功");
            } else {
                System.out.println("文件夹创建失败");
            }
        }
        String path=UPLOAD_FOLDER+ UUID.randomUUID()+".jpg";
        BASE64Decoder decoder = new BASE64Decoder();
        try {
            OutputStream outputStream=new FileOutputStream(path);
            byte[] imageByte=decoder.decodeBuffer(imageBase64);
            for (int i = 0; i < imageByte.length; ++i) {
                if (imageByte[i] < 0) {
                    imageByte[i] += 256;
                }
            }
            outputStream.write(imageByte);
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return this.ajaxSuccess(path);
    }

昨天遇到一个错误

Communications link failure

一开始以为是连接池的连接调用问题,发现重启库后修改timeout以后也解决不了,最后只能想是不是url出了问题,发现是域名过期。
所以这个错误可能的原因有:
1.调用了未关闭的连接池连接
2.url出错

启动前端页面:命令行窗口下到前端页面的目录,http-server 开启

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值