美文网首页springboot
210606:http post 方法传递参数-SpringBo

210606:http post 方法传递参数-SpringBo

作者: 弹钢琴的崽崽 | 来源:发表于2021-06-06 18:35 被阅读0次

    一. http post 方法传递参数的2种方式

    try{
        HttpPost httpPost = new HttpPost(url);
        StringEntity stringEntity = new StringEntity(param);//param参数,可以为"key1=value1&key2=value2"的一串字符串
        stringEntity.setContentType("application/x-www-form-urlencoded");
        httpPost.setEntity(stringEntity);
        HttpClient client = new DefaultHttpClient(); 
        HttpResponse httpResponse = client.execute(httpPost);
        String result = EntityUtils.toString(httpResponse.getEntity(), HTTP.UTF_8);
    } catch(IOException e){
    }
    

    有的时候我们不想要通过上面的方式来传递参数,因为考虑请求接口时我比较喜欢的方式是直接把key和value连成一串,如"key1=value1&key2=value2"来作为参数,这样http get和post的方法都可以用同样的结构来作为参数,于是http post的方法请求服务器数据时可以用下面的方法来实现.

    List<NameValuePair>list = new ArrayList<NameValuePair>();
    for (int i = 0; i < keys.length; i++) {
        list.add(new BasicNameValuePair(keys[i], values[i]));
    }
    HttpPost httpRequst = new HttpPost(urlString);
    httpRequst.setEntity(new UrlEncodedFormEntity(list,HTTP.UTF_8));
    

    二. SpringBoot整合websocket实现群聊

    前言:

    这里不做springboot框架搭建步骤,只做具体的实现,代码里有具体注释,所以不做多解释这里。

    代码里可能有相关日志的输出用到了slf4j

    1. 引入WebSocket依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-websocket</artifactId>
    </dependency>
    

    2. 写入WebSocket配置类

    @Configuration
    public class WebSocketConfig {
        //实例化一个Bean对象
        @Bean
        public ServerEndpointExporter serverEndpointExporter() {
            return new ServerEndpointExporter();
        }
    }
    

    3. 写入WebSocket群聊Controller控制层

    @Slf4j
    @Component
    @ServerEndpoint("/groupChat/{Group_no}/{username}")
    public class GroupChatController {
        // 保存 组id->组成员 的映射关系 之所以使用ConcurrentHashMap因为这个是线程安全的,里面采用了分段锁而HashMap是线程不安全的
        private static ConcurrentHashMap<String, List<Session>> groupMemberInfoMap = new ConcurrentHashMap<>();
    
        // 收到消息调用的方法,群成员发送消息
        @OnMessage
        public void onMessage(@PathParam("Group_no") String Group_no,
                              @PathParam("username") String username, String message) {
            //得到当前群的所有会话,也就是所有用户
            List<Session> sessionList = groupMemberInfoMap.get(Group_no);
            // 遍历Session集合给每个会话发送文本消息
            sessionList.forEach(item -> {
                try {
                    String text = username + ": " + message;
                    item.getBasicRemote().sendText(text);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            });
        }
    
        /**
         * 建立连接调用的方法,群成员加入
         * @param session 会话
         * @param Group_no 群id
         */
        @OnOpen
        public void onOpen(Session session, @PathParam("Group_no") String Group_no) {
            //得到当前群的所有会话,也就是所有用户
            List<Session> sessionList = groupMemberInfoMap.get(Group_no);
            if (sessionList == null) {
                sessionList = new ArrayList<>();
                groupMemberInfoMap.put(Group_no,sessionList);
            }
            sessionList.add(session);
            log.info("连接建立");
            log.info("群号: {}, 群人数: {}", Group_no, sessionList.size());
        }
    
        // 关闭连接调用的方法,群成员退出
        @OnClose
        public void onClose(Session session, @PathParam("Group_no") String Group_no) {
            List<Session> sessionList = groupMemberInfoMap.get(Group_no);
            sessionList.remove(session);
            log.info("连接关闭");
            log.info("群号: {}, 群人数: {}", Group_no, sessionList.size());
        }
    
        // 传输消息错误调用的方法
        @OnError
        public void OnError(Throwable error) {
            log.info("连接出错:{}",error.getMessage());
        }
    }
    

    4. 配置文件

    # 服务端口
    server.port=8080
    

    5. 前端html,注释是全套的,自己一边用一边理解

    <!DOCTYPE html>
    <html>
    <head>
        <title>测试WebSocket</title>
    </head>
    <body>
    <div>
        
    </div>
    <center>
    <div>
        <h1>WebSocket群聊</h1>
        <input type="text" id="Group_no" placeholder="请输入房间号"/><br>
        <input type="text" id="nickname" placeholder="请输入昵称"/><br>
        <input type="submit" value="连接" onclick="connect()" /><br>
        <textarea rows="3" cols="20" id="content"></textarea><br>
        <input type="submit" value="发送" onclick="start()" />
        <br>
    </div>
    <div id="messages"></div>
    </center>
    <script type="text/javascript">
        var webSocket = null;
        //收到消息
        function onMessage(event) {
            document.getElementById('messages').innerHTML
                += '<br />' + event.data;
        }
        //建立连接
        function onOpen(event) {
            document.getElementById('messages').innerHTML
                = '连接已经建立';
        }
        //发生错误
        function onError(event) {
            alert("发生错误");
            webSocket = null;
        }
        //连接关闭
        function onClose(event) {
            alert("连接关闭");
            webSocket = null;
        }
        //连接
        function connect() {
            //获取群号
            var Group_no = document.getElementById('Group_no').value;
            //获取昵称
            var nickname = document.getElementById('nickname').value;
            //验证非法数据
            if (url == '' || nickname == '') {
                alert("群号和用户名不能为空");
                return;
            }
            //验证是否已经建立连接
            if(webSocket!=null){
                alert("已经建立过连接,如需重新建立连接,请自行更改逻辑,或者重新刷新页面");
                return; 
            }
            //创建Websocket连接url
            var url = 'ws://localhost:8080/groupChat/' + Group_no + '/' + nickname;
            //实例化WebSocket
            webSocket = new WebSocket(url);
            //出现错误
            webSocket.onerror = function(event) {
                onError(event)
            };
            //调用创建连接
            webSocket.onopen = function(event) {
                onOpen(event)
            };
            //调用收到消息
            webSocket.onmessage = function(event) {
                onMessage(event)
            };
            //调用关闭连接
            webSocket.onclose = function(event) {
                onClose(event)
            };
        }
        //开始发送
        function start() {
            //获取发送的内容
            var text = document.getElementById('content').value;
            if(text== ''){
                alert("发送内容不允许为空");
                return;
            }
            if(webSocket==null){
                alert("请先建立连接");
                return;
            }
            //调用WebSocket发送的方法
            webSocket.send(text);
            //初始化文本域的内容为空
            document.getElementById('content').value = '';
        }
    </script>
    </body>
    </html>
    

    原文地址:https://blog.csdn.net/qq_41741884/article/details/103832925

    三. springboot跨域请求解决方案+前后端分离跨域问题其他解决方案

    简述跨域问题

    1. SpringBoot跨域请求

    1.1 直接采用SpringBoot的注解@CrossOrigin

    Controller层在需要跨域的类或者方法上加上该注解即可。

    1.2 处理跨域请求的Configuration

    CrossOriginConfig.java
    继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer接口

    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.CorsRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    
    /**
     * AJAX请求跨域
     * @author Mr.W
     * @time 2018-08-13
     */
    @Configuration
    public class CorsConfig extends WebMvcConfigurerAdapter {
        static final String ORIGINS[] = new String[] { "GET", "POST", "PUT", "DELETE" };
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedOrigins("*").allowCredentials(true).allowedMethods(ORIGINS)
                    .maxAge(3600);
        }
    }
    

    1.3 采用过滤器的方式

     @Component
    public class CORSFilter implements Filter {
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
                throws IOException, ServletException {
            HttpServletResponse res = (HttpServletResponse) response;
            res.addHeader("Access-Control-Allow-Credentials", "true");
            res.addHeader("Access-Control-Allow-Origin", "*");
            res.addHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT");
            res.addHeader("Access-Control-Allow-Headers", "Content-Type,X-CAF-Authorization-Token,sessionToken,X-TOKEN");
            if (((HttpServletRequest) request).getMethod().equals("OPTIONS")) {
                response.getWriter().println("ok");
                return;
            }
            chain.doFilter(request, response);
        }
        @Override
        public void destroy() {
        }
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    }
    

    1.4 方式4

    引入maven依赖:

     <dependency>
        <groupId>io.projectreactor</groupId>
        <artifactId>reactor-core</artifactId>
        <version>RELEASE</version>
    </dependency>
    
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.HttpStatus;
    import org.springframework.http.server.reactive.ServerHttpRequest;
    import org.springframework.http.server.reactive.ServerHttpResponse;
    import org.springframework.web.cors.reactive.CorsUtils;
    import org.springframework.web.server.ServerWebExchange;
    import org.springframework.web.server.WebFilter;
    import org.springframework.web.server.WebFilterChain;
    import reactor.core.publisher.Mono;
    
    
    /**
     * @author JiaweiWu
     * @create 2018/3/22.
     */
    @Configuration
    public class RouteConfiguration {
        //这里为支持的请求头,如果有自定义的header字段请自己添加(不知道为什么不能使用*)
        private static final String ALLOWED_HEADERS = "x-requested-with, authorization, Content-Type, Authorization, credential, X-XSRF-TOKEN,token,username,client";
        private static final String ALLOWED_METHODS = "*";
        private static final String ALLOWED_ORIGIN = "*";
        private static final String ALLOWED_Expose = "*";
        private static final String MAX_AGE = "18000L";
    
        @Bean
        public WebFilter corsFilter() {
            return (ServerWebExchange ctx, WebFilterChain chain) -> {
                ServerHttpRequest request = ctx.getRequest();
                if (CorsUtils.isCorsRequest(request)) {
                    ServerHttpResponse response = ctx.getResponse();
                    HttpHeaders headers = response.getHeaders();
                    headers.add("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
                    headers.add("Access-Control-Allow-Methods", ALLOWED_METHODS);
                    headers.add("Access-Control-Max-Age", MAX_AGE);
                    headers.add("Access-Control-Allow-Headers", ALLOWED_HEADERS);
                    headers.add("Access-Control-Expose-Headers", ALLOWED_Expose);
                    headers.add("Access-Control-Allow-Credentials", "true");
                    if (request.getMethod() == HttpMethod.OPTIONS) {
                        response.setStatusCode(HttpStatus.OK);
                        return Mono.empty();
                    }
                }
                return chain.filter(ctx);
            };
        }
    }
    

    2. 前后分离的跨域问题其他解决方案

    2.1 Nginx服务器反向代理

    通过反向代理服务器监听同端口,同域名的访问,不同路径映射到不同的地址,比如,在nginx服务器中,监听同一个域名和端口,不同路径转发到客户端和服务器,把不同端口和域名的限制通过反向代理,来解决跨域的问题。

    server {
            listen       80;
            server_name  abc.com;
            #charset koi8-r;
            #access_log  logs/host.access.log  main;
    
            location /client { #访问客户端路径
                proxy_pass http://localhost:81;
                proxy_redirect default;
            }
            location /apis { #访问服务器路径
                rewrite  ^/apis/(.*)$ /$1 break;
                proxy_pass   http://localhost:82;
           }
    }
    

    或者直接在Nginx中进行配置

    location / {
       add_header Access-Control-Allow-Origin *;
       add_header Access-Control-Allow-Headers X-Requested-With;
       add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS;
    
       if ($request_method = 'OPTIONS') {
         return 204;
       }
    }
    

    四. oracle排序时把null值放在最后

    今天在做项目的时候遇到一个数据排序的问题,当排序字段为空时,空值会排在数字的前面,这样的排序会非常难看,经过一番努力,终于找到原因了。因为ORACLE认为空值是最大的值,所以将SQL语句改为 ...order by ”排序字段" desc nulls last ;

    nulls first :将null排在最前面。

    null last :将null排在最后面。

    相关文章

      网友评论

        本文标题:210606:http post 方法传递参数-SpringBo

        本文链接:https://www.haomeiwen.com/subject/kzbheltx.html