ssm separated front and rear ends - return data encapsulation, exception handling, cross-domain problem is solved.

Previous I wrote IDEA + maven build around the end of the separation ssm environment before and after basic ssm end of the separation shelves take up, but still there are some problems. For example: data is not returned for dispensing (with bugs), abnormalities such as 400,404,405,500 not commonly used to capture, cross-domain problem. This article will resolve these issues.

One problem: the return of packaging data

1. Create OutputJson util package in return for unified data constraints

package com.hsy.sms.util;

import java.io.Serializable;
import com.alibaba.fastjson.JSON;

public class OutputJson implements Serializable {
    /**
     * 返回客户端统一格式,包括状态码,提示信息,以及业务数据
     */
    private static final long serialVersionUID = 1L;
    //状态码
    private int code;
    //必要的提示信息
    private String msg;
    //业务数据
    private Object data;

    public OutputJson(int code,String msg){
        this.code = code;
        this.msg = msg;
//        this.data = data;
    }

    public int getCode() {
        return code;
    }
    public void setCode(int code) {
        this.code = code;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }
    public String toString(){
//        if(null == this.data){
//            this.setData(new Object());
//        }
        return JSON.toJSONString(this);
    }
}

2, create a global exception ReturnFormat definitions and methods for call

package com.hsy.sms.util;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class ReturnFormat {
    private static Map<String,String> messageMap =new HashMap();
    //初始化状态码与文字说明
    static {

        messageMap.put("400", "Bad Request!");
        messageMap.put("401", "NotAuthorization");

        messageMap.put("404", "Resource is not available");

        messageMap.put("405", "Method Not Allowed");
        messageMap.put("406", "Not Acceptable");
        messageMap.put("500", "Internal Server Error");

    }
    //出现异常时调用
    public static String retParam(int code) {
        OutputJson json = new OutputJson(code, messageMap.get(String.valueOf(code)));
        return json.toString();
    }
    //正常时调用
    public static String retData(Object data){
        OutputJson json = new OutputJson(200, "ok!");
        json.setData(data);
        return json.toString();
    }
}

3, the normal use of the program to return the package type

@RequestMapping(value = "/login", method = RequestMethod.POST, consumes="application/x-www-form-urlencoded")
    @ResponseBody
    public Object selectUserInfo(@RequestParam(value="uid") int uid,@RequestParam(value="password") String pwd_id) throws Exception {

        User user = userService.getUserInfoById(uid);
        if(user == null ){
            return ReturnFormat.retData("用户不存在");
        }else if(user.getPwd_id().equals(pwd_id)){
            /**
             * 将密码隐藏
             * 将密码设置为null
             * com.alibaba.fastjson.JSON.toJSONString()方法将自动不返回为空的字段
             */
            user.setPwd_id(null);
            return ReturnFormat.retData(user);
        }else{
            return ReturnFormat.retData("密码错误");
        }
    }

4, write abnormal enhancement of class RestExceptionHandler

package com.hsy.sms.handler;

import com.hsy.sms.util.ReturnFormat;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.io.IOException;

@ControllerAdvice
public class RestExceptionHandler {
    
    //400错误
    @ExceptionHandler({HttpMessageNotReadableException.class})
    @ResponseBody
    public String requestNotReadable(HttpMessageNotReadableException ex){
        System.out.println("400..requestNotReadable");
        ex.printStackTrace();
        return ReturnFormat.retParam(400 );
    }
    //400错误
    @ExceptionHandler({TypeMismatchException.class})
    @ResponseBody
    public String requestTypeMismatch(TypeMismatchException ex){
        System.out.println("400..TypeMismatchException");
        ex.printStackTrace();
        return ReturnFormat.retParam(400 );
    }
    //400错误
    @ExceptionHandler({MissingServletRequestParameterException.class})
    @ResponseBody
    public String requestMissingServletRequest(MissingServletRequestParameterException ex){
        System.out.println("400..MissingServletRequest");
        ex.printStackTrace();
        return ReturnFormat.retParam(400 );
    }

    //405错误
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    @ResponseBody
    public String request405(){
        System.out.println("405...");
        return ReturnFormat.retParam(405 );
    }
    //406错误
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    @ResponseBody
    public String request406(){
        System.out.println("404...");
        return ReturnFormat.retParam(406 );
    }
    //500错误
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    @ResponseBody
    public String server500(RuntimeException runtimeException){
        System.out.println("500...");
        return ReturnFormat.retParam(406 );
    }

}
对于全局异常的处理笔者也百度也很多,试过很多方法比如:@CrossOrigin注解等等,但都不好使。皇天不负有心人,终于在一篇<a href="https://www.cnblogs.com/nosqlcoco/p/5562107.html">springmvc 通过异常增强返回给客户端统一格式</a>博客中找到了解决方法。这时我耳边响起了一句话:“问题一定会解决的,如果你还没有解决说明还没到最后”。不过还有一个小bug(返回异常为中文时会出现???的乱码。

补充:ssm前后端分离中对于404异常的捕获
在全局异常捕获中加入
    /**
     * me 404-NOT_FOUND
     * @param e
     * @return
     */
    @ExceptionHandler(NoHandlerFoundException.class)
    @ResponseBody
    public String handlerNotFoundException(NoHandlerFoundException e)
    {
        System.out.println("请求的资源不可用");
        return ReturnFormat.retParam(404);
    }
在web.xml--servlet中加入
<!--因为DispatcherServlet源码中对于throwExceptionIfNoHandlerFound 默认是 false 我们需要在初始化DispatcherServlet时将参数值更改为true.-->
    <init-param>
      <param-name>throwExceptionIfNoHandlerFound</param-name>
      <param-value>true</param-value>
    </init-param>

Question three: cross-domain issues

在前后端分离过程必然会遇到跨域问题具体原因感兴趣的可以移步<a href="https://www.cnblogs.com/Juaoie/p/9786313.html">ajax中的json和jsonp详解</a><a href="https://www.cnblogs.com/Juaoie/p/11692819.html">浏览器的同源策略和跨域详解(内含故事解析</a>这里我就不说这段离奇曲折的解决过去与故事了。话不多说直接上解决方法

1, to achieve Filter interface setting response header

package com.hsy.sms.util;

import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletResponse;

public class SimpleCORSFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
         HttpServletResponse httpResponse = (HttpServletResponse) response;
        httpResponse.addHeader("Access-Control-Allow-Origin", "*");
        //httpResponse.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        httpResponse.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,access_token,refresh_token");
        httpResponse.setHeader("Access-Control-Allow-Methods", "GET, PUT, DELETE, POST");
        httpResponse.setHeader("Access-Control-Allow-Credentials", "true");
        httpResponse.setHeader("Access-Control-Max-Age", "0");
        httpResponse.setContentType("text/html;charset=UTF-8");
        httpResponse.setHeader("XDomainRequestAllowed","1");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {

    }
}

2, was added the custom filter in web.xml

  <!-- 跨域过滤 -->
  <filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>com.hsy.sms.util.SimpleCORSFilter</filter-class>
  </filter>
  <filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

Guess you like

Origin www.cnblogs.com/shaoyu/p/11701242.html