How to run Retrovit2 Json RecyclerView in fragment? - json

So i using retrofit2 to fetch my json into my main activity it runs smoothly, but im using bottom navigation so i should convert my code from activity into fragment.
my code didnt show error after i debug it, it shows force close when the fragment opened
This is my Fragment Code:
package com.itsalex.helios.fragment;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.itsalex.helios.Adapter;
import com.itsalex.helios.ApiClient;
import com.itsalex.helios.ApiInterface;
import com.itsalex.helios.Contact;
import com.itsalex.helios.R;
import com.itsalex.helios.activity.CartActivity;
import com.itsalex.helios.activity.ProdukActivity;
import com.itsalex.helios.adapters.HorizontalAdapter;
import com.itsalex.helios.adapters.VerticalAdapter;
import com.itsalex.helios.model.Food;
import com.itsalex.helios.model.GeneralFood;
import com.itsalex.helios.recycleFragment;
import com.itsalex.helios.rest.RetrofitClient;
import com.itsalex.helios.rest.RetrofitInterface;
import java.util.ArrayList;
import java.util.List;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class StatusFragment extends Fragment {
// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private static final String ARG_PARAM1 = "param1";
private static final String ARG_PARAM2 = "param2";
// TODO: Rename and change types of parameters
private String mParam1;
private String mParam2;
private OnFragmentInteractionListener mListener;
public StatusFragment() {
// Required empty public constructor
}
/*private appController mController;*/
public List<Contact> contacts;
public Adapter adapter;
private RecyclerView recyclerView;
protected Handler handler;
private ApiInterface apiInterface;
ProgressBar progressBar;
TextView search;
String[] item;
private Call<ResponseBody> result;
public static recycleFragment newInstance(String param1, String param2) {
recycleFragment fragment = new recycleFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View v;
v = inflater.inflate(R.layout.fragment_recycle, container, false);
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);
progressBar = v.findViewById(R.id.prograss);
recyclerView = v.findViewById(R.id.frg_recyclerView);
handler = new Handler();
contacts = new ArrayList<>();
recyclerView.setHasFixedSize(true);
LinearLayoutManager mLayoutManager = new LinearLayoutManager(getContext());
recyclerView.setLayoutManager(mLayoutManager);
//adapter = new Adapter(getContext(), contacts, recyclerView, recyclerView, false);
adapter = new Adapter(contacts, getContext());
recyclerView.setAdapter(adapter);
fetchContact("users", "");
return v;
}
public void fetchContact(String type, String key){
apiInterface = ApiClient.getApiClient().create(ApiInterface.class);
Call<List<Contact>> call = apiInterface.getContact(type, key);
call.enqueue(new Callback<List<Contact>>() {
#Override
public void onResponse(Call<List<Contact>> call, Response<List<Contact>> response) {
progressBar.setVisibility(View.GONE);
contacts = response.body();
adapter = new Adapter(contacts, getContext());
recyclerView.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
#Override
public void onFailure(Call<List<Contact>> call, Throwable t) {
progressBar.setVisibility(View.GONE);
Toast.makeText(getContext(), "Error\n"+t.toString(), Toast.LENGTH_LONG).show();
}
});
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
/*if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}*/
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
this is my adapter activity
package com.itsalex.helios;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
public class Adapter extends RecyclerView.Adapter<Adapter.MyViewHolder> {
private List<Contact> contacts;
private Context context;
public Adapter(List<Contact> contacts, Context context) {
this.contacts = contacts;
this.context = context;
}
#Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
return new MyViewHolder(view);
}
#Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.name.setText(contacts.get(position).getName());
holder.email.setText(contacts.get(position).getEmail());
}
#Override
public int getItemCount() {
return contacts.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder{
TextView name,email;
public MyViewHolder(View itemView) {
super(itemView);
name = itemView.findViewById(R.id.name);
email = itemView.findViewById(R.id.email);
}
}
}
In the Logcat it shows error
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at com.itsalex.helios.Adapter.getItemCount(Adapter.java:40)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:3722)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3527)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:4082)
at android.view.View.layout(View.java:16992)
at android.view.ViewGroup.layout(ViewGroup.java:5409)
at android.widget.RelativeLayout.onLayout(RelativeLayout.java:1077)
at android.view.View.layout(View.java:16992)
at android.view.ViewGroup.layout(ViewGroup.java:5409)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:16992)
at android.view.ViewGroup.layout(ViewGroup.java:5409)
at android.support.design.widget.HeaderScrollingViewBehavior.layoutChild(HeaderScrollingViewBehavior.java:132)
at android.support.design.widget.ViewOffsetBehavior.onLayoutChild(ViewOffsetBehavior.java:42)
at android.support.design.widget.AppBarLayout$ScrollingViewBehavior.onLayoutChild(AppBarLayout.java:1361)
at android.support.design.widget.CoordinatorLayout.onLayout(CoordinatorLayout.java:894)
at android.view.View.layout(View.java:16992)
at android.view.ViewGroup.layout(ViewGroup.java:5409)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:16992)
at android.view.ViewGroup.layout(ViewGroup.java:5409)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1702)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1556)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1465)
at android.view.View.layout(View.java:16992)
at android.view.ViewGroup.layout(ViewGroup.java:5409)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:16992)
at android.view.ViewGroup.layout(ViewGroup.java:5409)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1702)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1556)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1465)
at android.view.View.layout(View.java:16992)
at android.view.ViewGroup.layout(ViewGroup.java:5409)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:579)
at android.widget.FrameLayout.onLayout(FrameLayout.java:514)
at android.view.View.layout(View.java:16992)
at android.view.ViewGroup.layout(ViewGroup.java:5409)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2483)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2185)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1314)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7057)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:829)
at android.view.Choreographer.doCallbacks(Choreographer.java:606)
at android.view.Choreographer.doFrame(Choreographer.java:576)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:815)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6934)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
i google it and i didnt find the answer, what should i do?
Thanks in advance

You have not initialised your progress bar.Use findViewById to set progressbar to your required progressbar.

Related

Upload excel file content to mysql using Spring boot and UI

I'm trying to upload excel file content to mysql using Spring boot with the help of upload file UI. Need help with that.
But i'm facing Whitelabel Error Page. I've tried couple of things but no luck yet.
Project View
ReadFileApplication.java
package com.springboot.file.parsefiles;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
#Configuration
#EnableAutoConfiguration
#ComponentScan(basePackages= {"com.springboot.file.parsefiles.controller"})
#SpringBootApplication
#Component
public class ReadFileApplication {
public static void main(String[] args) {
SpringApplication.run(ReadFileApplication.class, args);
}
}
ReadFileConrtroller.java
package com.springboot.file.parsefiles.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import com.springboot.file.parsefiles.service.ReadFileService;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import com.springboot.file.parsefiles.model.User;
#RestController
public class ReadFileController
{
#Autowired private ReadFileService readFileService;
#GetMapping(value="/ ")
public String home(Model model)
{
model.addAttribute("user", new User());
List<User> users = ReadFileService.findAll();
model.addAttribute("users", users);
return "view/users";
}
#PostMapping(value="/fileupload")
public String uploadFile(#ModelAttribute User user, RedirectAttributes redirectAttributes)
{
#SuppressWarnings("unused")
boolean isFlag = readFileService.saveDataFromUploadFile(user.getFile());
return "redirect:/";
}
}
ReadFileRepository.java
package com.springboot.file.parsefiles.repository;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;
import com.springboot.file.parsefiles.model.User;
#Repository
public interface ReadFileRepository extends CrudRepository<User, Long>
{
}
ReadFileService.java
package com.springboot.file.parsefiles.service;
import java.util.List;
import org.springframework.web.multipart.MultipartFile;
import com.springboot.file.parsefiles.model.User;
public interface ReadFileService
{
List<User> findAll = null;
static List<User> findAll()
{
return null;
}
boolean saveDataFromUploadFile(MultipartFile file);
}
ReadFileServiceImpl.java
package com.springboot.file.parsefiles.service;
import java.util.List;
import com.springboot.file.parsefiles.service.ReadFileService;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import com.springboot.file.parsefiles.model.User;
import com.springboot.file.parsefiles.repository.ReadFileRepository;
#Service
#Transactional
public class ReadFileServiceImpl implements ReadFileService
{
#Autowired private ReadFileRepository readFileRepository;
public List<User> findAll()
{
return (List<User>) readFileRepository.findAll();
}
#Override
public boolean saveDataFromUploadFile(MultipartFile file) {
#SuppressWarnings("unused")
boolean isFlag = false;
String extension = FilenameUtils.getExtension(file.getOriginalFilename());
if(extension.equalsIgnoreCase("json"))
{
isFlag = realDataFromJson(file);
}else if(extension.equalsIgnoreCase("csv"))
{
isFlag = realDataFromCsv(file);
}
return false;
}
private boolean realDataFromCsv(MultipartFile file)
{
return false;
}
private boolean realDataFromJson(MultipartFile file)
{
return false;
}
}
Applicatiopn.properties
spring.datasource.url = jdbc:mysql://localhost:3306/sampledatabase
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.testWhileIdle = true
spring.datasource.validationQuery = SELECT 1
spring.jpa.show-sql = true
spring.jpa.hibernate.ddl-auto = update
spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=500MB
Edit:
***************************
APPLICATION FAILED TO START
***************************
Description:
Field readFileService in com.springboot.file.parsefiles.controller.ReadFileController required a bean of type 'com.springboot.file.parsefiles.service.ReadFileService' that could not be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'com.springboot.file.parsefiles.service.ReadFileService' in your configuration.
Update your controller as below
#PostMapping(value="/fileupload")
public String uploadFile(#RequestParam MultipartFile file, RedirectAttributes redirectAttributes)
{
#SuppressWarnings("unused")
boolean isFlag = readFileService.saveDataFromUploadFile(file);
return "redirect:/";
}
Next i used apache-poi library to convert excel file to list of model object in service class. So my service method is as below
#Autowired
private IPoiji poijiImpl;
#Override
public boolean saveDataFromUploadFile(MultipartFile file) {
List<UserDTO> uploadedUserList = = poijiImpl.fromExcel(file.getOriginalFilename(), file.getInputStream(),UserDTO.class);
// here i can call repository methods to save data in database
}

How to parse recursive JSON object using JAXB

Below is my JSON, how to parse it using jaxb, note the depth and key of categories would change
{
"categories":{
"categoryHierarchy":[
{
"hierarchy":{
"SDG--1513417390":{
"SD-1501363638":{
"D-HS-MM4":{
"CL-HS-MM4-DEFAULT":{
"C-HS-MM4-MM0203":{
}
}
}
}
}
},
"precedence":1
}
]
}
}
After trying multiple things I was able to parse the recursive category structure.
package com.example;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pearson.aem.aemcore.pim.dto.com.example.Example;
class Parser{
private transient static ObjectMapper jsonMapper;
public static void main (String [] args) throws IOException
{
jsonMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
String response = "{\"categoryHierarchy\":[{\"hierarchy\":{\"SDG--1513417390\":{\"SD-1501363638\":{\"D-HS-MM4\":{\"CL-HS-MM4-DEFAULT\":{\"C-HS-MM4-MM0203\":{}}}}}},\"precedence\":1}]}";
InputStream stream = new ByteArrayInputStream(response.getBytes());
Example ex = unmarshalJson(stream, Example.class);
System.out.println(ex.getCategoryHierarchy().get(0).getHierarchy1().getAdditionalProperties());
//System.out.println(ex.getCategoryHierarchy().get(0).getHierarchy().getAdditionalProperties().get("SDG--1513417390").keySet.iterator().next());
}
public static <T> T unmarshalJson(final InputStream result, final Class<T> declaredType) throws IOException
{
return (T) jsonMapper.readValue(result, declaredType);
}
}
----------------
package com.example;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlElement;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.pearson.aem.aemcore.pim.dto.CategoryElementDTO;
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Example
{
#XmlElement(
name = "categoryHierarchy")
private List<CategoryHierarchy> categoryHierarchy;
#XmlElement(
name = "relatedCategories")
private Map<String, CategoryElementDTO> relatedCategories;
public List<CategoryHierarchy> getCategoryHierarchy()
{
return categoryHierarchy;
}
public void setCategoryHierarchy(List<CategoryHierarchy> categoryHierarchy)
{
this.categoryHierarchy = categoryHierarchy;
}
public Map<String, CategoryElementDTO> getRelatedCategories()
{
return relatedCategories;
}
public void setRelatedCategories(Map<String, CategoryElementDTO> relatedCategories)
{
this.relatedCategories = relatedCategories;
}
}
------------
package com.example;
public class CategoryHierarchy
{
private Hierarchy hierarchy;
private Integer precedence;
public Hierarchy getHierarchy()
{
return hierarchy;
}
public void setHierarchy(Hierarchy hierarchy)
{
this.hierarchy = hierarchy;
}
public Integer getPrecedence()
{
return precedence;
}
public void setPrecedence(Integer precedence)
{
this.precedence = precedence;
}
}
---------------
package com.example;
import java.util.HashMap;
import java.util.Map;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Hierarchy
{
#JsonIgnore
private Map<String, Object> additionalProperties = new HashMap<String, Object>();
#JsonAnyGetter
public Map<String, Object> getAdditionalProperties()
{
return this.additionalProperties;
}
#JsonAnySetter
public void setAdditionalProperty(String name, Object value)
{
this.additionalProperties.put(name, value);
}
}

Error:Error: This class should provide a default constructor (a public constructor with no arguments) (AppName.CustomListAdapter) [Instantiatable]

I am trying to create a signed apk for my application but i get an error after clicking finish after the create a signed apk dialogue.
Error:Error: This class should provide a default constructor (a public constructor with no arguments) (MYAPPNAME.CustomListAdapter) [Instantiatable]
Java code below
import android.app.Activity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.TextView;
public class CustomListAdapter extends ArrayAdapter {
private final Activity context;
private final String[] itemname;
private final Integer[] imgid;
public CustomListAdapter(Activity context, String[] itemname, Integer[] imgid) {
super(context, R.layout.mylist, itemname);
// TODO Auto-generated constructor stub
this.context=context;
this.itemname=itemname;
this.imgid=imgid;
}
public View getView(int position,View view,ViewGroup parent) {
LayoutInflater inflater=context.getLayoutInflater();
View rowView=inflater.inflate(R.layout.mylist, null,true);
TextView txtTitle = (TextView) rowView.findViewById(R.id.item);
ImageView imageView = (ImageView) rowView.findViewById(R.id.icon);
//TextView extratxt = (TextView) rowView.findViewById(R.id.textView1);
txtTitle.setText(itemname[position]);
imageView.setImageResource(imgid[position]);
// extratxt.setText("Description "+itemname[position]);
return rowView;
};
Help Please
The issue was solved in the build.gradle file. Inside the android string add the following:
lintOptions {
abortOnError false
}

Not getting the answer if add method is static otherwise non-static add method is working

SimpleA.java class is target class. I have to mock getList method of SimpleB.java class if add method is non-static its working fine but it is showing problem with static add method
SimpleA.java
import java.util.ArrayList;
public class SimpleA {
private static SimpleB obj1 ;
public static int add(){
ArrayList<Integer> arr1 = obj1.getList1();
ArrayList<Integer> arr2 = obj1.getList2();
int res=0;
for(Integer val : arr1){
res+=val;
}
for(Integer val1 : arr2){
res+=val1;
}
return res;
}
}
SimpleB.java
import java.util.ArrayList;
import java.util.Iterator;
public class SimpleB {
public ArrayList<Integer> getList1(){
System.out.println("inside class SimpleB and getlist1");
ArrayList<Integer> lst1 = new ArrayList<Integer>();
lst1.add(10);
lst1.add(20);
return lst1;
}
public ArrayList<Integer> getList2(){
System.out.println("inside class SimpleB and getlist2");
ArrayList<Integer> lst2 = new ArrayList<Integer>();
lst2.add(30);
lst2.add(40);
return lst2;
}
}
SimpleATest.java
This is test class here I am testing for SimpleA.java class
import java.lang.reflect.Field;
import java.util.ArrayList;
import org.easymock.EasyMock;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;
#RunWith(PowerMockRunner.class)
#PrepareForTest({SimpleA.class})
public class SimpleATest {
SimpleA simpleA1;
SimpleB mockSample;
#Before
public void setUp(){
ArrayList<Integer> lst = new ArrayList<Integer>();
lst.add(30);
lst.add(40);
lst.add(100);
simpleA1 = new SimpleA();
mockSample = PowerMock.createMock(SimpleB.class);
PowerMock.mockStatic(SimpleA.class);
EasyMock.expect(mockSample.getList1()).andReturn(lst);
EasyMock.expect(mockSample.getList2()).andReturn(lst);
PowerMock.replay(mockSample);
Whitebox.setInternalState(simpleA1,mockSample);
System.out.println("Init method is invoked");
}
#Test
public void testAdd(){
int res = simpleA1.add();
System.out.println("res = "+res);
}
#After
public void destroy(){
System.out.println("Destroy method is invoked");
}
}
I have seen this behavior in the past. The way around is to set first the default answer on the static methods and then fill in the behavior as such:
#RunWith(PowerMockRunner.class)
#PrepareForTest(MyClassWithStaticMethods.class)
public testClass{
#Test
public void testSomething(){
// this prepares the class; all static methods get a default return value (in this case type Object is returned and the default returned object is null)
PowerMockito.mockStatic(MyClassWithStaticMethods.class, new Answer<Object>()
{
#Override
public Object answer(InvocationOnMock invocation) throws Throwable {
return null;
}
});
//Now the class is prepared, we can just change the behaviour of the static method in the way we would like.
String in = "example input string";
String out = "example output string";
// after preparing the class, you can override a specific static method. For this example we use the matchers, could also have used Matchers.any(String.class) or any other matcher combination as long as it maps on the method.
PowerMockito.when(MyClassWithStaticMethods.staticMethod(Matchers.eq(in))).thenReturn(out);
}
//..body
}

Spring, thymeleaf, JPA/hibernate, mysql UTF-8 characters persist in db

I have problem with persisting polish PL-pl locale characters in mysql db.
I know that is common issue, and out there in the internet is many solution to this. But I cant figure it out. I think I've tried everything.
All my web page correctly encode and display UTF-8 characters (static from html and from db)
Problem cames when I save somthing in db using form on my application. So I think it is tightly related to JDBC, JPA and hibernate.
Here is my configuration:
application.properties
#DB Properties:
# Mysql
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3300/derp?characterEncoding=UTF-8
hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
db.username=root
db.password=motorolaa835
# H2
#db.driver=org.h2.Driver
#db.url=jdbc:h2:~/sts/derp/db/derp_db
#hibernate.dialect=org.hibernate.dialect.H2Dialect
#db.username=root
#Hibernate Configuration:
hibernate.show_sql=true
hibernate.hbm2ddl.auto=update
#hibernate.hbm2ddl.auto=create
hibernate.connection.CharSet=utf8
hibernate.connection.characterEncoding=utf8
hibernate.connection.useUnicode=true
services.entitymanager.packages.to.scan=com.derp
cms.entitymanager.packages.to.scan=com.derp.cms.model
common.entitymanager.packages.to.scan=com.derp.common.model
procedure.entitymanager.packages.to.scan=com.derp.procedure.model
Initializer
package com.derp.common.init;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.DispatcherServlet;
public class Initializer implements WebApplicationInitializer {
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(WebAppConfig.class);
ctx.register(ThymeleafConfig.class);
servletContext.addListener(new ContextLoaderListener(ctx));
ctx.setServletContext(servletContext);
Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
servlet.addMapping("/");
servlet.setAsyncSupported(true);
servlet.setLoadOnStartup(1);
// Allow to use Put and Delete method for REST architecture
registerCharachterEncodingFilter(servletContext);
registerHiddenFieldFilter(servletContext);
}
private void registerCharachterEncodingFilter(ServletContext aContext) {
CharacterEncodingFilter cef = new CharacterEncodingFilter();
cef.setForceEncoding(true);
cef.setEncoding("UTF-8");
aContext.addFilter("charachterEncodingFilter", cef).addMappingForUrlPatterns(null ,true, "/*");
}
private void registerHiddenFieldFilter(ServletContext aContext) {
aContext.addFilter("hiddenHttpMethodFilter", new HiddenHttpMethodFilter()).addMappingForUrlPatterns(null ,true, "/*");
}
}
WebAppConfig
package com.derp.common.init;
import java.util.Properties;
import javax.annotation.Resource;
import javax.sql.DataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.http.MediaType;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
//import com.derp.common.wicketView.HomePage;
#Configuration
#ComponentScan("com.derp")
#EnableWebMvc
#EnableTransactionManagement
#PropertySource("classpath:application.properties")
public class WebAppConfig extends WebMvcConfigurerAdapter {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO = "hibernate.hbm2ddl.auto";
private static final String PROPERTY_NAME_HIBERNATE_CONNECTION_CHARSET = "hibernate.connection.CharSet";
private static final String PROPERTY_NAME_HIBERNATE_CONNECTION_CHARACTERENCODING = "hibernate.connection.characterEncoding";
private static final String PROPERTY_NAME_HIBERNATE_CONNECTION_USEUNICODE = "hibernate.connection.useUnicode";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES = "services.entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON = "common.entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS = "cms.entitymanager.packages.to.scan";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_PROCEDURE = "procedure.entitymanager.packages.to.scan";
#Resource
private Environment env;
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
dataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
dataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
dataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return dataSource;
}
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactoryBean = new LocalSessionFactoryBean();
sessionFactoryBean.setDataSource(dataSource());
//sessionFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
sessionFactoryBean.setPackagesToScan(new String[] {
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_SERVICES),
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_COMMON),
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_CMS),
env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN_PROCEDURE)
});
sessionFactoryBean.setHibernateProperties(hibProperties());
return sessionFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_HBM2DDL_AUTO));
properties.put(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARSET, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARSET));
properties.put(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARACTERENCODING, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CONNECTION_CHARACTERENCODING));
properties.put(PROPERTY_NAME_HIBERNATE_CONNECTION_USEUNICODE, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_CONNECTION_USEUNICODE));
properties.put("jadira.usertype.autoRegisterUserTypes", "true");
return properties;
}
#Bean
public HibernateTransactionManager transactionManager() {
HibernateTransactionManager transactionManager = new HibernateTransactionManager();
transactionManager.setSessionFactory(sessionFactory().getObject());
return transactionManager;
}
#Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
// Simple strategy: only path extension is taken into account
configurer.favorPathExtension(true).
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType(MediaType.TEXT_HTML).
mediaType("html", MediaType.TEXT_HTML).
mediaType("xml", MediaType.APPLICATION_XML).
mediaType("json", MediaType.APPLICATION_JSON);
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/img/**").addResourceLocations("/WEB-INF/img/*");
registry.addResourceHandler("/css/**").addResourceLocations("/WEB-INF/css/*");
registry.addResourceHandler("/js/**").addResourceLocations("/WEB-INF/js/*");
registry.addResourceHandler("/lib/**").addResourceLocations("/WEB-INF/lib/*");
}
}
ThymeleafConfig
package com.derp.common.init;
import nz.net.ultraq.thymeleaf.LayoutDialect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.thymeleaf.spring4.SpringTemplateEngine;
import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ServletContextTemplateResolver;
#Configuration
public class ThymeleafConfig {
#Bean
public ServletContextTemplateResolver templateResolver() {
ServletContextTemplateResolver resolver = new ServletContextTemplateResolver();
resolver.setPrefix("/WEB-INF/view/");
resolver.setSuffix(".html");
resolver.setTemplateMode("HTML5");
resolver.setOrder(1);
resolver.setCacheable(false);
return resolver;
}
#Bean
public SpringTemplateEngine templateEngine() {
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver());
templateEngine.addDialect(new LayoutDialect());
//templateEngine.addDialect(new SpringStandardDialect());
return templateEngine;
}
#Bean
public ThymeleafViewResolver thymeleafViewResolver() {
ThymeleafViewResolver resolver = new ThymeleafViewResolver();
resolver.setTemplateEngine(templateEngine());
resolver.setCharacterEncoding("UTF-8");
return resolver;
}
}
Edit
There is no utf-8 characters when using this method on controller
controller
#RequestMapping(value="/test", method=RequestMethod.PUT)
#ResponseBody
public String ajaxTest() {
return "Characters test: ęółąśżźćń";
}
and the javasscript ajax method
$(document).ready(function() {
$('h1').click(function() {
$.ajax({
type: "PUT",
url: "/derp/procedury/test",
data: "none",
success: function (response, status, xhr) {
showNotifications(status, xhr.responseText);
},
error: function (response, status, xhr) {
showNotifications('error', JSON.stringify(response));
showNotifications('error', status);
showNotifications('error', xhr);
}
});
});
The result I get is:
Characters test: ?�???????
Please give some helpful suggestions. Thanks in advance.
I had the same problem, I've added the following filter config to my MyServletInitializer
and there's no more problem (in my case other configs don't work):
public class MyServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
....
#Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceEncoding(true);
return new Filter[]{filter};
}
....
}
Working solution:
Code to add in initializer class:
private void registerCharachterEncodingFilter(ServletContext aContext) {
CharacterEncodingFilter cef = new CharacterEncodingFilter();
cef.setForceEncoding(true);
cef.setEncoding("UTF-8");
aContext.addFilter("charachterEncodingFilter", cef).addMappingForUrlPatterns(null ,true, "/*");
}
and then call it in initializer in
onStartup method
with ServletContext:
registerCharachterEncodingFilter