how can i use json in javascript made by spring controller jackson?

Viewed 36

this is my first time to use spring and i don't know about ajax so i just try to make json string in spring controller and send it to javascript and in external js file i want to draw some chart with chart.js but there is problem I think that I do send json string to script file and console.log command show the right json string but I couldn't use my json, for JSON.parse() because

"VM241:1 Uncaught SyntaxError: Unexpected token ''', "'" is not valid JSON at JSON.parse ()"

here is my controller code and customizeSerializer class

package com.datacampus.biohealth2.serializer;

import com.datacampus.biohealth2.dto.PerDayNutritionDto;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

public class PerNutritionDtoSerializer extends JsonSerializer<PerDayNutritionDto> {

    @Override
    public void serialize(PerDayNutritionDto perDayNutritionDto, JsonGenerator jsonGenerator,
                          SerializerProvider serializerProvider)throws IOException, JsonProcessingException {
        jsonGenerator.writeStartObject();
        jsonGenerator.writeFieldName("kcal");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getKcal()));

        jsonGenerator.writeFieldName("protein");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getProtein()));

        jsonGenerator.writeFieldName("Sugar");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getSugar()));

        jsonGenerator.writeFieldName("Sodium");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getSodium()));

        jsonGenerator.writeFieldName("Saturated_fat");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getSaturatedFat()));

        jsonGenerator.writeFieldName("Caffeine");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getCaffeine()));

        jsonGenerator.writeFieldName("drink_kcal");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getDrink_kcal()));

        jsonGenerator.writeFieldName("drink_protein");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getDrink_protein()));

        jsonGenerator.writeFieldName("drink_sugar");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getDrink_sugar()));

        jsonGenerator.writeFieldName("drink_Sodium");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getDrink_Sodium()));

        jsonGenerator.writeFieldName("drink_Caffeine");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getDrink_caffeine()));

        jsonGenerator.writeFieldName("drink_saturated_fat");
        jsonGenerator.writeString(String.valueOf(perDayNutritionDto.getDrink_saturatedFat()));

        jsonGenerator.writeEndObject();
    }

} 

and this is my CustomSerializer for make it at module


package com.datacampus.biohealth2.serializer;

import com.datacampus.biohealth2.dto.PerDayNutritionDto;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.io.IOException;

public class CustomSerializer {


    public static ObjectMapper getCustomObjectMapper(){
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(PerDayNutritionDto.class,new PerNutritionDtoSerializer());
        objectMapper.registerModule(simpleModule);

        return objectMapper;
    }



}




and this is my controller to send json


 @GetMapping("/show")
    public String showHealthInformation(@AuthenticationPrincipal UserDetails userDetails, Model model) throws JsonProcessingException {

        String userEmail = userDetails.getUsername();
        Member member = memberRepository.findByEmail(userEmail);
        HealthInformation healthInformation = healthInformationRepository.findByMember_Id(member.getId());
        model.addAttribute("userName",member.getName());
        model.addAttribute("user_weight",healthInformation.getWeight());
        model.addAttribute("user_height",healthInformation.getHeight());
        model.addAttribute("user_gender",healthInformation.getGender());
        model.addAttribute("user_activity",healthInformation.getActivityType());
        model.addAttribute("user_age",healthInformation.getAge());

        PerDayNutrition perDayNutrition  = perDayNutritionRepository
                .findPerDayNutritionByHealthInformation_Id(healthInformation.getId());
        PerDayNutritionDto perDayNutritionDto = perDayNutritionService.getPerDayNutritionDto(perDayNutrition);


        ObjectMapper objectMapper = CustomSerializer.getCustomObjectMapper();

        String perDayNutritionJson = objectMapper.writerWithDefaultPrettyPrinter()
                .writeValueAsString(perDayNutritionDto);
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("\'");
        stringBuilder.append(perDayNutritionJson);
        stringBuilder.append("\'");
        perDayNutritionJson = stringBuilder.toString();
        model.addAttribute("perDayNutritionJson",perDayNutritionJson);
        System.out.println(perDayNutritionJson);

        return "healthInformation/showHealthInformation"; 

    } 

and this is my html using thymeleaf


<script th:inline="javascript" type="text/javascript">
    /*<![CDATA[*/
    let perDayNutritionJson = [[${perDayNutritionJson}]];
    alert(perDayNutritionJson);
    /*]]>*/
</script>

<script src="/vendor/jquery/jquery.min.js"></script>
<script src="/vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

<!-- Core plugin JavaScript-->
<script src="/vendor/jquery-easing/jquery.easing.min.js"></script>

<!-- Custom scripts for all pages-->
<script src="/js/sb-admin-2.min.js"></script>

<!-- Page level plugins -->
<script src="/vendor/chart.js/Chart.min.js"></script>

<!-- Page level custom scripts -->
<script src="/js/demo/chart-area-demo.js"></script>
<script src="/js/demo/chart-pie-demo.js"></script>
<script src="/js/demo/chart-bar-demo.js"></script>

and this is chart-bar-demo.js file to draw bar chart with the json string that I sent at controller and this chart.js is not done yet


// Set new default font family and font color to mimic Bootstrap's default styling
Chart.defaults.global.defaultFontFamily = 'Nunito', '-apple-system,system-ui,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif';
Chart.defaults.global.defaultFontColor = '#858796';

function number_format(number, decimals, dec_point, thousands_sep) {
  // *     example: number_format(1234.56, 2, ',', ' ');
  // *     return: '1 234,56'
  number = (number + '').replace(',', '').replace(' ', '');
  var n = !isFinite(+number) ? 0 : +number,
      prec = !isFinite(+decimals) ? 0 : Math.abs(decimals),
      sep = (typeof thousands_sep === 'undefined') ? ',' : thousands_sep,
      dec = (typeof dec_point === 'undefined') ? '.' : dec_point,
      s = '',
      toFixedFix = function(n, prec) {
        var k = Math.pow(10, prec);
        return '' + Math.round(n * k) / k;
      };
  // Fix for IE parseFloat(0.55).toFixed(0) = 0;
  s = (prec ? toFixedFix(n, prec) : '' + Math.round(n)).split('.');
  if (s[0].length > 3) {
    s[0] = s[0].replace(/\B(?=(?:\d{3})+(?!\d))/g, sep);
  }
  if ((s[1] || '').length < prec) {
    s[1] = s[1] || '';
    s[1] += new Array(prec - s[1].length + 1).join('0');
  }
  return s.join(dec);
}

// Bar Chart Example
console.log(perDayNutritionJson);
perDayNutritionJson = perDayNutritionJson[0][0];
// Preserve newlines, etc. - use valid JSON
perDayNutritionJson = perDayNutritionJson.replace(/\\n/g, "\\n")
    .replace(/\\'/g, "\\'")
    .replace(/\\"/g, '\\"')
    .replace(/\\&/g, "\\&")
    .replace(/\\r/g, "\\r")
    .replace(/\\t/g, "\\t")
    .replace(/\\b/g, "\\b")
    .replace(/\\f/g, "\\f");
// Remove non-printable and other non-valid JSON characters
perDayNutritionJson = perDayNutritionJson.replace(/[\u0000-\u0019]+/g,"");

var perDay = JSON.parse(perDayNutritionJson);
console.log(perDay)

var ctx = document.getElementById("myBarChart");
var myBarChart = new Chart(ctx, {
  type: 'bar',
  data: {
    labels: ["kcal", "Sugar", "Saturated_fat", "Caffeine", "Protein", "Sodium"],
    datasets: [{
      label: "영양성분 일일 권장량",
      backgroundColor: "#4e73df",
      hoverBackgroundColor: "#2e59d9",
      borderColor: "#4e73df",
      data: [ perDay.kcal,perDay.protein,perDay.Sugar,perDay.Sodium,perDay.Saturated_fat,perDay.Caffeine],
    }],
  },
  options: {
    maintainAspectRatio: false,
    layout: {
      padding: {
        left: 10,
        right: 25,
        top: 25,
        bottom: 0
      }
    },
    scales: {
      xAxes: [{
        time: {
          unit: 'month'
        },
        gridLines: {
          display: false,
          drawBorder: false
        },
        ticks: {
          maxTicksLimit: 6
        },
        maxBarThickness: 25,
      }],
      yAxes: [{
        ticks: {
          min: 0,
          max: 400,
          maxTicksLimit: 5,
          padding: 10,
          // Include a dollar sign in the ticks
          callback: function(value, index, values) {
            return  number_format(value);
          }
        },
        gridLines: {
          color: "rgb(234, 236, 244)",
          zeroLineColor: "rgb(234, 236, 244)",
          drawBorder: false,
          borderDash: [2],
          zeroLineBorderDash: [2]
        }
      }],
    },
    legend: {
      display: false
    },
    tooltips: {
      titleMarginBottom: 10,
      titleFontColor: '#6e707e',
      titleFontSize: 14,
      backgroundColor: "rgb(255,255,255)",
      bodyFontColor: "#858796",
      borderColor: '#dddfeb',
      borderWidth: 1,
      xPadding: 15,
      yPadding: 15,
      displayColors: false,
      caretPadding: 10,
      callbacks: {
        label: function(tooltipItem, chart) {
          var datasetLabel = chart.datasets[tooltipItem.datasetIndex].label || '';
          return datasetLabel + number_format(tooltipItem.yLabel);
        }
      }
    },
  }
});

in this code i just wanna check console.log(perDay) this first but there is always error and

// Bar Chart Example
console.log(perDayNutritionJson);
perDayNutritionJson = perDayNutritionJson[0][0];
// Preserve newlines, etc. - use valid JSON
perDayNutritionJson = perDayNutritionJson.replace(/\\n/g, "\\n")
    .replace(/\\'/g, "\\'")
    .replace(/\\"/g, '\\"')
    .replace(/\\&/g, "\\&")
    .replace(/\\r/g, "\\r")
    .replace(/\\t/g, "\\t")
    .replace(/\\b/g, "\\b")
    .replace(/\\f/g, "\\f");
// Remove non-printable and other non-valid JSON characters
perDayNutritionJson = perDayNutritionJson.replace(/[\u0000-\u0019]+/g,"");

var perDay = JSON.parse(perDayNutritionJson);
console.log(perDay)


I think at this part there is a problem but I don't know exactly what it is.

0 Answers
Related