Spring MVC mapping view for Google-GSON?

后端 未结 2 2001
孤城傲影
孤城傲影 2021-01-31 21:46

Does anyone know if there is a Spring MVC mapping view for Gson? I\'m looking for something similar to org.springframework.web.servlet.view.json.MappingJacksonJsonView.

2条回答
  •  谎友^
    谎友^ (楼主)
    2021-01-31 22:12

    I would recommend to extend AbstractView just like the MappingJacksonJsonView does.

    Personally, for JSON, I prefer to use @Responsebody, and just return the object rather than a model and view, this makes it easier to test. If you would like to use GSON for that, just create a custom HttpMessageConverter like this:

    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    import com.google.gson.JsonParseException;
    import com.google.gson.reflect.TypeToken;
    import com.vitalimages.string.StringUtils;
    import org.springframework.http.HttpInputMessage;
    import org.springframework.http.HttpOutputMessage;
    import org.springframework.http.MediaType;
    import org.springframework.http.converter.AbstractHttpMessageConverter;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.http.converter.HttpMessageNotWritableException;
    import org.springframework.stereotype.Component;
    
    import java.io.BufferedWriter;
    import java.io.IOException;
    import java.io.OutputStreamWriter;
    import java.lang.reflect.Type;
    import java.nio.charset.Charset;
    import java.sql.Timestamp;
    
    @Component
    public class GSONHttpMessageConverter extends AbstractHttpMessageConverter {
    
        public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
    
        private GsonBuilder gsonBuilder = new GsonBuilder()
                .excludeFieldsWithoutExposeAnnotation()
                .setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ")
                .registerTypeAdapter(Timestamp.class, new GSONTimestampConverter());
    
        public GSONHttpMessageConverter() {
            super(new MediaType("application", "json", DEFAULT_CHARSET));
        }
    
        @Override
        protected boolean supports(Class clazz) {
            // should not be called, since we override canRead/Write instead
            throw new UnsupportedOperationException();
        }
    
        @Override
        public boolean canRead(Class clazz, MediaType mediaType) {
            return MediaType.APPLICATION_JSON.isCompatibleWith(mediaType);
        }
    
        public boolean canWrite(Class clazz, MediaType mediaType) {
            return MediaType.APPLICATION_JSON.isCompatibleWith(mediaType);
        }
    
        public void registerTypeAdapter(Type type, Object serializer) {
            gsonBuilder.registerTypeAdapter(type, serializer);
        }
    
        @Override
        protected Object readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
            try {
                Gson gson = gsonBuilder.create();
                return    gson.fromJson(StringUtils.convertStreamToString(inputMessage.getBody()), clazz);
            } catch (JsonParseException e) {
                throw new HttpMessageNotReadableException("Could not read JSON: " + e.getMessage(), e);
            }
        }
    
        @Override
        protected void writeInternal(Object o, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
            Type genericType = TypeToken.get(o.getClass()).getType();
    
            BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputMessage.getBody(), DEFAULT_CHARSET));
            try {
                // See http://code.google.com/p/google-gson/issues/detail?id=199 for details on SQLTimestamp conversion
                Gson gson = gsonBuilder.create();
                writer.append(gson.toJson(o, genericType));
            } finally {
                writer.flush();
                writer.close();
            }
        }
    }
    
    
    

    And then add it to your converter list in your handler adapter like this:

    @Bean
    public HandlerAdapter handlerAdapter() {
        final AnnotationMethodHandlerAdapter handlerAdapter = new AnnotationMethodHandlerAdapter();
        handlerAdapter.setAlwaysUseFullPath(true);
        List> converterList = new ArrayList>();
        converterList.addAll(Arrays.asList(handlerAdapter.getMessageConverters()));
        converterList.add(jibxHttpMessageConverter);
        converterList.add(gsonHttpMessageConverter);
        handlerAdapter.setMessageConverters(converterList.toArray(new HttpMessageConverter[converterList.size()]));
        return handlerAdapter;
    }
    

    提交回复
    热议问题